hashicorp/nomad · error
unexpected ClockSkewLeeway type: %v
Error message
unexpected ClockSkewLeeway type: %v
What it means
Returned in api/acl.go's unmarshal logic when the ClockSkewLeeway JSON value is neither a duration string nor a float64 (nanoseconds). Part of the same type-switch chain that decodes leeway fields on ACL auth method clock skew configuration.
Source
Thrown at api/acl.go:984
}
case float64:
c.NotBeforeLeeway = time.Duration(v)
default:
return fmt.Errorf("unexpected NotBeforeLeeway type: %v", v)
}
}
if aux.ClockSkewLeeway != nil {
switch v := aux.ClockSkewLeeway.(type) {
case string:
if v != "" {
if c.ClockSkewLeeway, err = time.ParseDuration(v); err != nil {
return err
}
}
case float64:
c.ClockSkewLeeway = time.Duration(v)
default:
return fmt.Errorf("unexpected ClockSkewLeeway type: %v", v)
}
}
return nil
}
// OIDCClientAssertionKeySource specifies what key material should be used
// to sign an OIDCClientAssertion.
type OIDCClientAssertionKeySource string
const (
// OIDCKeySourceNomad signs the OIDCClientAssertion JWT with Nomad's
// internal private key. Its public key is exposed at /.well-known/jwks.json
OIDCKeySourceNomad OIDCClientAssertionKeySource = "nomad"
// OIDCKeySourcePrivateKey signs the OIDCClientAssertion JWT with
// key material defined in OIDCClientAssertion.PrivateKey
OIDCKeySourcePrivateKey OIDCClientAssertionKeySource = "private_key"
// OIDCKeySourceClientSecret signs the OIDCClientAssertion JWT with
// ACLAuthMethod.ClientSecretView on GitHub (pinned to 482b49bf1a)
Solutions
- Send ClockSkewLeeway as a duration string like "2m" or numeric nanoseconds.
- Fix the producing code/serializer to emit the expected type.
- If the field is optional, omit it entirely instead of sending a null/typed placeholder.
Example fix
// before
{"ClockSkewLeeway": ["2", "minutes"]}
// after
{"ClockSkewLeeway": "2m"} Defensive patterns
Strategy: validation
Validate before calling
if payload.ClockSkewLeeway != nil && !isDurationOrNumber(*payload.ClockSkewLeeway) {
return fmt.Errorf("ClockSkewLeeway must be a duration string or nanosecond number")
} Type guard
func coerceClockSkew(v interface{}) (time.Duration, bool) {
switch t := v.(type) {
case string:
d, err := time.ParseDuration(t)
return d, err == nil
case float64:
return time.Duration(t), true
}
return 0, false
} Prevention
- Omit optional leeway fields instead of sending typed placeholders.
- Keep one shared JSON model for auth methods between producer and consumer.
- Cover leeway encoding in integration tests.
When it happens
Trigger: Submitting or decoding auth method JSON where `ClockSkewLeeway` is a non-string, non-numeric value (object, bool, null dereference into the aux interface).
Common situations: Clients building payloads programmatically with incorrectly typed fields; JSON produced by another language where durations serialize as objects; API upgrades changing field encoding expectations.
Related errors
- unexpected ExpirationLeeway type: %v
- unexpected NotBeforeLeeway type: %v
- unexpected ExpirationLeeway type: %v
- unexpected NotBeforeLeeway type: %v
- default auth config text could not be deserialized: %v
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/0d8b43c3ac36fcef.
Report an issue: GitHub.