Skip to content

Incorrect HTTP status code for expired passcode (408 instead of 400/422) #2398

@jaffarkeikei

Description

@jaffarkeikei

Description

Found in backend/handler/passcode.go around line 319: When a passcode expires, the API returns http.StatusRequestTimeout (408), which is semantically incorrect for this use case.

Current Code

businessError = echo.NewHTTPError(http.StatusRequestTimeout, "passcode request timed out").SetInternal(errors.New(fmt.Sprintf("createdAt: %s -> lastVerificationTime: %s", passcode.CreatedAt, lastVerificationTime))) // TODO: maybe we should use BadRequest, because RequestTimeout might be to technical and can refer to different error

Problem

HTTP 408 Request Timeout is meant for situations where:

  • The client took too long to send the request
  • The server timed out waiting for the request body
  • Network/connection issues caused a timeout

It should NOT be used when:

  • Application-level validation fails (like an expired passcode)
  • Business logic determines something is no longer valid

Impact

  1. Client confusion: HTTP clients may retry 408 responses automatically, which is inappropriate for expired passcodes
  2. Monitoring issues: 408s typically indicate infrastructure problems, not application-level validation failures
  3. API semantics: Violates HTTP specification intent

Recommended Fix

Use a more appropriate status code:

Option 1: 400 Bad Request (Recommended)

businessError = echo.NewHTTPError(http.StatusBadRequest, "passcode has expired").SetInternal(errors.New(fmt.Sprintf("createdAt: %s -> lastVerificationTime: %s", passcode.CreatedAt, lastVerificationTime)))

Option 2: 422 Unprocessable Entity

businessError = echo.NewHTTPError(http.StatusUnprocessableEntity, "passcode has expired").SetInternal(errors.New(fmt.Sprintf("createdAt: %s -> lastVerificationTime: %s", passcode.CreatedAt, lastVerificationTime)))

Location

backend/handler/passcode.go, line ~319 (in the Finish method)

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions