---
title: "Postel's Law"
source: "/reference/postels-law"
description: "Interfaces benefit when they accept reasonable variation in user input while producing clear, predictable output."
---
# Postel's Law

Interfaces benefit when they accept reasonable variation in user input while producing clear, predictable output.



### Principle

Interfaces benefit when they accept reasonable variation in user input while producing clear, predictable output.

### Why it matters

Originally associated with robust network protocol implementation, the principle translates cautiously to UX: people type phone numbers with spaces, paste formatted IDs, use capitalization inconsistently, and make recoverable formatting mistakes. A product can normalize benign variation without silently changing meaning. Security-sensitive or ambiguous input requires stricter handling.

### Deeper design interpretation

For user interfaces, Postel's principle is useful when it encourages safe tolerance of harmless variation. People paste formatted phone numbers, use spaces in identifiers, enter dates according to locale, vary capitalization, and upload data with small inconsistencies. Requiring users to manually normalize information that the system can interpret unambiguously creates avoidable friction.

Tolerance has a boundary. Silent coercion can corrupt data, weaken security, or create expensive downstream errors. The interface should be flexible about syntax while remaining strict about meaning.

Layr should therefore distinguish **benign variation**, **recoverable invalidity**, and **semantic ambiguity**. Each deserves a different response.

### What the agent should reason about

Inspect parsers, validators, locale handling, error messaging, and downstream consequences. If multiple interpretations are possible, the correct recommendation is usually clarification or confirmation rather than automatic normalization.

Batch operations deserve special attention because one malformed record should not automatically destroy progress for thousands of valid records when isolation is possible.

### Common failure patterns

- Phone or ID fields reject spaces and punctuation the backend could normalize safely.
- Date parsing ignores locale and silently swaps month/day meaning.
- One invalid row aborts an entire import without recovery.
- The system transforms ambiguous input without showing the normalized result.
- Format instructions appear only after submission.

### Audit questions

- Is the rejected variation semantically harmless?
- Can the system normalize it deterministically?
- Would leniency introduce ambiguity, security risk, or data corruption?
- Can errors be isolated and recovered without discarding valid work?

### Example agent finding

> **Medium — Phone validation rejects benign formatting.** The field rejects `+52 669 123 4567` even though the backend stores E.164 numbers and can normalize spaces safely. Accept common formatting, normalize before storage, and reserve validation errors for values whose meaning cannot be determined.

### Agent directive

> Accept harmless input variation when meaning is unambiguous, normalize transparently, and be strict where ambiguity, security, money, or data integrity make leniency unsafe.

### Apply this when

- Forms, search, imports, phone numbers, dates, currency, identifiers, pasted content, file upload, and API-connected setup.

### Observable signals

- A field rejects formatting that can be normalized safely.
- Users must remove spaces, punctuation, or capitalization manually for no semantic reason.
- An import fails the entire batch because one row is malformed when isolation is possible.
- The system silently coerces ambiguous data into a different meaning.
- Validation explains format rules only after submission.

### Recommended actions

- Normalize benign syntax such as whitespace or common separators when safe.
- Parse with locale and domain context when available.
- Isolate invalid records and provide actionable recovery for batch processes.
- Show normalized values when the transformation could surprise users.
- Use strict validation for security boundaries and consequential ambiguity.

### Do not over-apply

Leniency must never become silent corruption. Reject or confirm input when multiple interpretations are plausible.

### Example

**Weak:** A phone field rejects '+52 669 123 4567' because the backend expects digits only.

**Stronger:** The field accepts common formatting, stores a normalized representation, and shows a clear validation message only when the number cannot be interpreted safely.

### Evaluation notes

- **Default severity:** Medium; high for silent coercion or data corruption.
- **Typical confidence:** High when validation rules and safe normalization are inspectable.
- **Primary evidence:** Validation code, parsers, accepted formats, error messages, data consequence.
- **Related rules:** Tesler's Law, Cognitive Load, Mental Model, Error Tolerance Application Layer

### References

- [Laws of UX — Postel's Law](https://lawsofux.com/postels-law/)
- [RFC 1122 — Robustness Principle context](https://www.rfc-editor.org/rfc/rfc1122)

## Related rules

- [Tesler's Law](/__layr/pages/reference/teslers-law.md)
- [Cognitive Load](/__layr/pages/reference/cognitive-load.md)
- [Mental Model](/__layr/pages/reference/mental-model.md)
- [Error Tolerance Application Layer](/__layr/pages/reference/interaction-performance-error-tolerance#error-tolerance-application-layer.md)

## Agent guidance

Review criteria, the finding contract a report must use, and worked examples.

Established principle; Layr interpretation and agent guidance. Category: Interaction, Performance & Error Tolerance.

## Retrieve
- Canonical page: https://layr.design/reference/postels-law
- Markdown for agents: https://layr.design/__layr/pages/reference/postels-law.md
- Reference map: https://layr.design/llms.txt
- Route index: https://layr.design/__layr/routes.toon

## Rule object
```yaml
rule:
  id: "postels-law"
  title: "Postel's Law"
  category: "Interaction, Performance & Error Tolerance"
  origin: established
  canonical_url: "https://layr.design/reference/postels-law"
  principle: "Interfaces benefit when they accept reasonable variation in user input while producing clear, predictable output."
  directive: "Accept harmless input variation when meaning is unambiguous, normalize transparently, and be strict where ambiguity, security, money, or data integrity make leniency unsafe."
  applies_when:
    - "Forms, search, imports, phone numbers, dates, currency, identifiers, pasted content, file upload, and API-connected setup."
  observable_signals:
    - "A field rejects formatting that can be normalized safely."
    - "Users must remove spaces, punctuation, or capitalization manually for no semantic reason."
    - "An import fails the entire batch because one row is malformed when isolation is possible."
    - "The system silently coerces ambiguous data into a different meaning."
    - "Validation explains format rules only after submission."
  audit_questions:
    - "Is the rejected variation semantically harmless?"
    - "Can the system normalize it deterministically?"
    - "Would leniency introduce ambiguity, security risk, or data corruption?"
    - "Can errors be isolated and recovered without discarding valid work?"
  recommended_actions:
    - "Normalize benign syntax such as whitespace or common separators when safe."
    - "Parse with locale and domain context when available."
    - "Isolate invalid records and provide actionable recovery for batch processes."
    - "Show normalized values when the transformation could surprise users."
    - "Use strict validation for security boundaries and consequential ambiguity."
  avoid_when:
    - "Leniency must never become silent corruption. Reject or confirm input when multiple interpretations are plausible."
  common_failure_patterns:
    - "Phone or ID fields reject spaces and punctuation the backend could normalize safely."
    - "Date parsing ignores locale and silently swaps month/day meaning."
    - "One invalid row aborts an entire import without recovery."
    - "The system transforms ambiguous input without showing the normalized result."
    - "Format instructions appear only after submission."
  evidence_types:
    - "Validation code"
    - "parsers"
    - "accepted formats"
    - "error messages"
    - "data consequence"
  default_severity: "Medium; high for silent coercion or data corruption."
  typical_confidence: "High when validation rules and safe normalization are inspectable."
  related_rules:
    - { id: "teslers-law", title: "Tesler's Law", url: "https://layr.design/reference/teslers-law" }
    - { id: "cognitive-load", title: "Cognitive Load", url: "https://layr.design/reference/cognitive-load" }
    - { id: "mental-model", title: "Mental Model", url: "https://layr.design/reference/mental-model" }
    - { id: "04", title: "Error Tolerance Application Layer", url: "https://layr.design/reference/interaction-performance-error-tolerance#error-tolerance-application-layer" }
```

## What to reason about
Inspect parsers, validators, locale handling, error messaging, and downstream consequences. If multiple interpretations are possible, the correct recommendation is usually clarification or confirmation rather than automatic normalization. Batch operations deserve special attention because one malformed record should not automatically destroy progress for thousands of valid records when isolation is possible.

## Routing
Route a review here when evidence is measurable in interaction behavior: latency, target geometry, validation, parsing, task completion, duplicate actions, failed input, or recovery. Prefer instrumented evidence over aesthetic judgment.

## Review procedure
For every finding:
1. Identify the exact component, state, route, or interaction.
2. State the observable evidence.
3. Name the principle that applies.
4. Explain the user consequence in the current context.
5. Estimate severity from the consequence, frequency, and reversibility.
6. Recommend the smallest change that addresses the issue while preserving the product's existing design system.
7. Lower confidence when intent, frequency, audience, device, or product constraints must be inferred.
8. Do not produce generic advice such as "improve hierarchy" or "make this clearer" without specifying what is wrong and why.

## Finding contract — emit exactly this shape
```yaml
finding:
  rule_id: string
  location: string
  evidence:
    - observable fact
  impact: string
  severity: low | medium | high | critical
  confidence: low | medium | high
  recommendation:
    change: string
    rationale: string
    preserve:
      - existing design-system behavior
      - valid product constraints
```

## Example finding for this rule
Medium — Phone validation rejects benign formatting. The field rejects +52 669 123 4567 even though the backend stores E.164 numbers and can normalize spaces safely. Accept common formatting, normalize before storage, and reserve validation errors for values whose meaning cannot be determined.

## Code reference

The same principle as markup. Compare the structure, not the class names.

```html
<!-- weak -->
<div class="example-ui example-ui-weak">
  <div class="scene-chrome">
    <span class="scene-chrome-app">Contacts</span>
    <span class="scene-chrome-view">Edit contact</span>
  </div>
  <div class="scene-body">
    <div class="scene-panel">
      <span class="scene-panel-title">Contact number</span>
      <div class="scene-field">
        <span class="scene-label">Phone</span>
        <span class="scene-input scene-input-error">+52 669 123 4567</span>
      </div>
      <span class="scene-field-error">Numbers only. No spaces or + sign.</span>
      <span class="scene-meta">Format rules appeared after submit.</span>
      <span class="scene-note">Rejects input the system can normalise safely</span>
    </div>
  </div>
</div>
```

```html
<!-- stronger -->
<div class="example-ui example-ui-strong">
  <div class="scene-chrome">
    <span class="scene-chrome-app">Contacts</span>
    <span class="scene-chrome-view">Edit contact</span>
  </div>
  <div class="scene-body">
    <div class="scene-panel">
      <span class="scene-panel-title">Contact number</span>
      <div class="scene-field">
        <span class="scene-label">Phone</span>
        <span class="scene-input scene-input-ok">+52 669 123 4567</span>
        <span class="scene-hint-line">Stored as +526691234567</span>
      </div>
      <div class="scene-row">
        <span class="scene-tag scene-tag-success">Accepted</span>
        <span class="scene-meta">Mexico · mobile</span>
      </div>
      <div class="scene-field">
        <span class="scene-label">Contract date</span>
        <span class="scene-input scene-input-warning">03/04/26</span>
      </div>
      <div class="scene-row">
        <span class="scene-meta">Two readings</span>
        <span class="scene-tag scene-tag-neutral">3 Apr 2026</span>
        <span class="scene-tag scene-tag-neutral">4 Mar 2026</span>
      </div>
      <span class="scene-note">Tolerant where meaning is safe · asks where it is not</span>
    </div>
  </div>
</div>
```

```css
/* declarations these studies depend on */
.example-ui { display: grid; grid-template-rows: auto minmax(0, 1fr); min-width: 0; min-height: 17rem; overflow: hidden; border: var(--border-thin) solid var(--color-border-strong); background: var(--color-background); color: var(--color-text); font-size: var(--text-xs); line-height: var(--leading-snug); }
.example-ui .scene-chrome { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-1) var(--space-2); padding: var(--space-2) var(--space-3); border-bottom: var(--border-thin) solid var(--color-border-strong); background: var(--color-surface); }
.example-ui .scene-chrome-app { font-size: var(--text-2xs); font-weight: 600; letter-spacing: var(--tracking-label); text-transform: uppercase; }
.example-ui .scene-chrome-view { color: var(--color-text-tertiary); font-size: var(--text-2xs); }
.example-ui .scene-body { display: grid; align-content: start; gap: var(--space-3); min-width: 0; padding: var(--space-3); }
.example-ui .scene-body:has(> .scene-panel:only-child) { align-content: stretch; }
.example-ui .scene-panel { display: grid; align-content: start; justify-items: start; gap: var(--space-2); min-width: 0; padding: var(--space-3); border: var(--border-thin) solid var(--color-border-strong); background: var(--color-surface-raised); }
.example-ui .scene-panel-title { font-size: var(--text-sm); font-weight: 600; letter-spacing: var(--tracking-heading); }
.example-ui .scene-row { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: var(--space-1) var(--space-2); width: 100%; min-width: 0; padding-block: var(--space-1); }
.example-ui .scene-panel > .scene-row + .scene-row { border-top: var(--border-thin) solid var(--color-border-subtle); }
.example-ui .scene-meta { color: var(--color-text-tertiary); font-size: var(--text-2xs); }
.example-ui .scene-note { width: 100%; padding-top: var(--space-2); border-top: var(--border-thin) solid var(--color-border-subtle); color: var(--color-text-tertiary); font-family: var(--font-mono); font-size: var(--text-2xs); line-height: var(--leading-snug); }
.example-ui .scene-tag { display: inline-block; padding: 0 var(--space-2); border: var(--border-thin) solid var(--color-border-strong); color: var(--color-text-secondary); font-size: var(--text-2xs); line-height: 1.6; white-space: nowrap; }
.example-ui .scene-tag-neutral { border-color: var(--color-border-strong); }
.example-ui .scene-tag-success { border-color: var(--color-success); color: var(--color-success); }
.example-ui .scene-field { display: grid; justify-items: stretch; gap: var(--space-1); width: 100%; }
.example-ui .scene-label { color: var(--color-text-secondary); font-size: var(--text-2xs); }
.example-ui .scene-input { display: flex; align-items: center; min-height: var(--space-8); min-width: 0; padding: 0 var(--space-2); border: var(--border-thin) solid var(--color-border-strong); background: var(--color-surface-raised); color: var(--color-text); overflow-wrap: anywhere; }
.example-ui .scene-input-error { border-color: var(--color-danger); }
.example-ui .scene-input-warning { border-color: var(--color-caution); }
.example-ui .scene-input-ok { border-color: var(--color-success); }
.example-ui .scene-hint-line { color: var(--color-text-tertiary); font-size: var(--text-2xs); }
.example-ui .scene-field-error { color: var(--color-danger); font-size: var(--text-2xs); }
.example-ui { min-height: 15rem; }

/* resolved values */
:root {
  --border-thin: 1px;
  --font-mono: "Geist Mono", "SFMono-Regular", Consolas, "Liberation Mono", monospace;
  --leading-snug: 1.35;
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-8: 2rem;
  --text-2xs: 0.6875rem;
  --text-sm: 0.875rem;
  --text-xs: 0.75rem;
  --tracking-heading: -0.025em;
  --tracking-label: 0.06em;
}
```

## Weak vs stronger
- Weak: A phone field rejects '+52 669 123 4567' because the backend expects digits only.
- Stronger: The field accepts common formatting, stores a normalized representation, and shows a clear validation message only when the number cannot be interpreted safely.

## Reporting rules
- Report only what the interface shows as observable evidence; phrase psychological or motivational effects as possible consequences.
- Returning no finding is a valid result when evidence is insufficient.
