Skip to content

RFC 2119 Keywords Guide

Deep dive into using RFC 2119 keywords effectively in specifications.

What is RFC 2119?

RFC 2119 is an Internet standards document that defines key words used to indicate requirement levels in formal specifications. These keywords have precise, standardized meanings that make requirements unambiguous.

  • RFC = Request for Comments (IETF standards document)
  • 2119 = Document number
  • Official Title: "Key words for use in RFCs to Indicate Requirement Levels"

The Five Keywords

SDD Tool uses five RFC 2119 keywords, each with specific implications for implementation.

1. SHALL / MUST

Meaning: Absolute requirement - this is mandatory

When to use:

  • Critical features that must be implemented
  • Security requirements
  • Core functionality
  • Mandatory constraints

Examples:

markdown
- The system SHALL authenticate all API requests
- The password field SHALL be encrypted
- The API SHALL return HTTP 401 for invalid tokens
- Users SHALL receive a confirmation email

Implementation implications:

  • Code MUST satisfy this requirement
  • Tests MUST verify compliance
  • Missing implementations are bugs
  • No exceptions without explicit approval

Test approach:

  • Write test to verify requirement is met
  • Test should fail if requirement is violated

2. SHOULD

Meaning: Recommended requirement - strongly suggested but not mandatory

When to use:

  • Important features that enhance usability
  • Best practices
  • Requirements that can have documented exceptions
  • Features that should be prioritized

Examples:

markdown
- The system SHOULD validate email format
- Error messages SHOULD be user-friendly
- The API SHOULD return structured error responses
- Login responses SHOULD complete within 500ms

Implementation implications:

  • Code SHOULD satisfy this requirement
  • Exceptions require documented justification
  • Missing implementation is a deviation (not a bug)
  • Team should consciously decide to skip

When might you not implement:

  • Time constraints require prioritization
  • Conflicting requirements exist
  • Alternative solutions better serve users
  • Technical limitations prevent it

Test approach:

  • Implement test for the requirement
  • Document why if not implemented
  • Consider re-prioritizing later

3. MAY

Meaning: Optional requirement - implementation may choose to include or exclude

When to use:

  • Nice-to-have features
  • Future extensions
  • Context-dependent functionality
  • Advanced features
  • Features dependent on external factors

Examples:

markdown
- The system MAY support biometric authentication
- Users MAY customize their dashboard layout
- The API MAY cache user preferences
- The system MAY support dark mode

Implementation implications:

  • Code may or may not satisfy this requirement
  • No requirement to implement
  • No requirement to test
  • No plan needed for non-implementation

When to use MAY carefully:

  • It's easy to overcomplicate specs with optional features
  • Distinguish between truly optional vs. should implement
  • Use sparingly for genuinely optional features

Test approach:

  • Optional: write test if implemented
  • No test needed if not implemented
  • Don't block on MAY requirements

4. SHALL NOT

Meaning: Forbidden behavior - must not do this

When to use:

  • Security constraints
  • Performance constraints
  • Compatibility requirements
  • Anti-patterns to avoid
  • Explicit forbidden behaviors

Examples:

markdown
- The system SHALL NOT store passwords in plaintext
- The API SHALL NOT expose internal error details
- Code SHALL NOT contain hardcoded API keys
- The UI SHALL NOT block the main thread

Implementation implications:

  • Code MUST NOT do this
  • Doing this is a violation (serious bug)
  • Tests MUST verify non-compliance
  • No exceptions without explicit approval

Test approach:

  • Write negative test to verify it doesn't happen
  • Test should fail if requirement is violated
  • Treat violations as critical bugs

5. SHOULD NOT

Meaning: Recommended against but not forbidden

When to use:

  • Anti-patterns to generally avoid
  • Discouraged but allowed implementations
  • Legacy compatibility concerns
  • Performance considerations

Examples:

markdown
- The system SHOULD NOT use nested callbacks
- User data SHOULD NOT be cached for more than 1 hour
- The API SHOULD NOT return more than 10,000 records
- The client SHOULD NOT retry indefinitely

Implementation implications:

  • Code SHOULD NOT do this
  • Exceptions may be documented and justified
  • Not implementing this pattern is better
  • Consider alternatives first

Test approach:

  • Test the preferred approach
  • Document why if violated
  • Plan to refactor if anti-pattern is used

Using Keywords Effectively

Keyword Selection Matrix

SituationKeywordReason
Non-negotiable requirementSHALLZero flexibility
Important but flexibleSHOULDAllows prioritization
Truly optionalMAYNo implementation pressure
Security/compliance constraintSHALL NOTPrevents harm
Best practice to avoidSHOULD NOTEncourages better design

Pairing Keywords

Requirement + Negation

Use complementary pairs:

markdown
### Authentication

- Users SHALL provide valid credentials
- The system SHALL NOT accept invalid tokens
- Users SHOULD change passwords regularly
- Users SHOULD NOT share their tokens

Different Aspects of Same Feature

markdown
### Email Notifications

- System SHALL send confirmation emails (function)
- Emails SHOULD be delivered within 5 minutes (quality)
- Emails MAY include personalization (enhancement)
- System SHALL NOT send after user unsubscribes (constraint)

Common Keyword Patterns

Pattern: Mandatory Feature with Quality Goals

markdown
### Pattern Example: User Login

- Users SHALL be able to log in (mandatory)
- Login response SHOULD complete within 500ms (quality)
- System SHOULD provide helpful error messages (usability)
- System SHALL NOT expose user existence (security)

Pattern: Core Feature + Nice-to-Have Extensions

markdown
### Pattern Example: Search

- System SHALL support text search (core)
- System SHOULD support advanced filters (enhancement)
- System SHOULD return results within 1 second (performance)
- Search MAY include spell correction (extension)

Common Mistakes and How to Avoid Them

Mistake 1: Using "Should" for Everything

Bad:

markdown
- The system should have user authentication
- Users should be able to log in
- Passwords should be secure

This is vague and creates uncertainty.

Good:

markdown
- The system SHALL have user authentication
- Users SHALL be able to log in with email/password
- Passwords SHALL be encrypted using bcrypt

Rule: If it's needed for the feature to work, use SHALL. If it's enhancement, use SHOULD.

Mistake 2: Forgetting the Negative Case

Incomplete:

markdown
- Valid passwords SHALL be accepted

Better:

markdown
- Valid passwords SHALL be accepted
- Invalid passwords SHALL be rejected

Rule: Consider both positive and negative cases.

Mistake 3: Mixing Levels of Specificity

Bad:

markdown
- Users SHALL be able to authenticate
- The bcrypt rounds SHALL be 10
- Passwords should be complex

Good:

markdown
### Authentication
- Users SHALL authenticate using email/password (feature)
- Passwords SHALL meet complexity requirements (constraint)

### Password Hashing
- Passwords SHALL be hashed with bcrypt (method)
- Bcrypt rounds SHALL be minimum 10 (parameter)

Rule: Group related requirements at same abstraction level.

Mistake 4: Overusing "Shall Not"

Bad:

markdown
- The system SHALL NOT have bugs
- The system SHALL NOT be slow
- The system SHALL NOT fail

These are too vague. Be specific about what's forbidden.

Good:

markdown
- The system SHALL NOT return passwords in responses
- The API SHALL NOT make unencrypted database calls
- Failed requests SHALL NOT lock user accounts

Rule: Use SHALL NOT for specific, checkable constraints.

Mistake 5: Confusing "May" with "Should"

Problem:

markdown
- The system MAY have a dark mode (is it really optional?)
- The system MAY load within 2 seconds (is this really optional?)

Better:

markdown
- If dark mode is truly optional for MVP: MAY
- If it's an expected feature: SHOULD
- If it's a critical requirement: SHALL
- If it's a performance SLA: SHOULD

Rule: Use MAY only for genuinely optional features, not for prioritization.

Writing Testable Requirements

Requirement Must Be Verifiable

Not testable:

markdown
- The system SHALL be user-friendly
- The API SHALL be efficient
- Users SHOULD have a good experience

Testable:

markdown
- The system SHALL have error messages in clear language
- API response time SHOULD be under 500ms
- 95% of users SHOULD find desired feature within 3 clicks

Actionable and Specific

Not specific:

markdown
- SHALL handle errors appropriately
- SHOULD work with different browsers
- MAY include security features

Specific:

markdown
- SHALL return HTTP 400 with error details for invalid input
- SHOULD support browsers released in last 2 years
- MAY implement HTTPS/TLS encryption

RFC 2119 Compliance Checklist

Before finalizing specifications:

  • [ ] Every requirement uses one of the five keywords (SHALL, SHOULD, MAY, SHALL NOT, SHOULD NOT)
  • [ ] Keywords are capitalized and bold (SHALL, SHOULD, etc.)
  • [ ] Each requirement is specific and testable
  • [ ] Negative cases are addressed (both SHALL and SHALL NOT)
  • [ ] Level of strictness matches actual priority
  • [ ] Team understands what each keyword means
  • [ ] Test plan aligns with keyword levels
  • [ ] Keywords are used consistently throughout spec

Quick Reference

KeywordStrictnessImplementationTesting
SHALLMandatoryMust implementMust test
SHOULDRecommendedShould implementShould test
MAYOptionalOptionalTest if implemented
SHALL NOTForbiddenMust not doMust test non-compliance
SHOULD NOTDiscouragedAvoidTest better approach

Learning Resources


Next: GIVEN-WHEN-THEN Scenarios

MIT License