gofiber/fiber · warning

ErrInvalidIdempotencyKey

ErrInvalidIdempotencyKey

Error message

%w: invalid length: %d != %d

What it means

Returned by the default KeyHeaderValidate (config.go:67-70) when the Idempotency-Key header is not exactly 36 characters (the length of a canonical UUID). The middleware propagates it to the client as the request error. It wraps ErrInvalidIdempotencyKey with the observed vs expected lengths.

Source

Thrown at middleware/idempotency/config.go:69

	// DisableValueRedaction turns off masking idempotency keys in logs and errors when set to true.
	//
	// Optional. Default: false
	DisableValueRedaction bool
}

// ConfigDefault is the default config
var ConfigDefault = Config{
	Next: func(c fiber.Ctx) bool {
		// Skip middleware if the request was done using a safe HTTP method
		return fiber.IsMethodSafe(c.Method())
	},

	Lifetime: 30 * time.Minute,

	KeyHeader: "X-Idempotency-Key",
	KeyHeaderValidate: func(k string) error {
		if l, wl := len(k), 36; l != wl { // UUID length is 36 chars
			return fmt.Errorf("%w: invalid length: %d != %d", ErrInvalidIdempotencyKey, l, wl)
		}

		return nil
	},

	KeepResponseHeaders: nil,

	Lock: nil, // Set in configDefault so we don't allocate data here.

	Storage:               nil, // Set in configDefault so we don't allocate data here.
	DisableValueRedaction: false,
}

// Helper function to set default values
func configDefault(config ...Config) Config {
	// Return default config if nothing provided
	if len(config) < 1 {
		cfg := ConfigDefault

View on GitHub (pinned to 9a4c7e57fe)

Solutions

  1. Send a RFC-4122 UUID v4 (with hyphens, 36 chars) in the X-Idempotency-Key header.
  2. Override Config.KeyHeaderValidate to accept your existing ID format instead of UUID length.
  3. If migrating ID formats, accept both old and new inside a custom KeyHeaderValidate.

Example fix

// before — short client-generated key
c.Req.Header.Set("X-Idempotency-Key", "order-123")

// after — full UUID
import "github.com/google/uuid"
c.Req.Header.Set("X-Idempotency-Key", uuid.NewString())

// or relax the validator in the server
app.Use(idempotency.New(idempotency.Config{
    KeyHeaderValidate: func(k string) error {
        if k == "" || len(k) > 128 { return idempotency.ErrInvalidIdempotencyKey }
        return nil
    },
}))
Defensive patterns

Strategy: validation

Validate before calling

// client-side: only send canonical UUIDs
import "github.com/google/uuid"

func idempotencyKey() string {
    return uuid.NewString() // always 36 chars
}

// server-side: accept your real ID format
app.Use(idempotency.New(idempotency.Config{
    KeyHeaderValidate: func(k string) error {
        if len(k) == 0 || len(k) > 128 {
            return idempotency.ErrInvalidIdempotencyKey
        }
        return nil
    },
}))

Prevention

When it happens

Trigger: A non-safe HTTP request (POST/PUT/PATCH/DELETE — Next skips only safe methods) carries an X-Idempotency-Key header whose length is not 36: e.g. a short counter ('1', '42'), a UUID without hyphens (32 chars), a UUID with braces, or a ULID/snowflake.

Common situations: Client library generates non-UUID request IDs; frontend sends its internal trace ID instead of a UUID; testing with hardcoded short keys; an older client format being migrated.

Related errors


AI-assisted analysis of gofiber/fiber@9a4c7e57fe (2026-08-04). Data as JSON: /data/errors/0f3f47a63ed6eac1.json. Report an issue: GitHub.