golang/go · error
crypto/rsa: invalid PSS salt length
Error message
crypto/rsa: invalid PSS salt length
What it means
Thrown by SignPSS when opts.SaltLength resolves to a value <= 0 that is neither PSSSaltLengthAuto (0) nor PSSSaltLengthEqualsHash (-1) — i.e. a negative number below -1, or it slipped past those two cases. The switch handles the two sentinels; the default branch rejects any remaining non-positive length. This is a general input validation, NOT FIPS-specific (it fires regardless of enforcement).
Source
Thrown at src/crypto/rsa/fips.go:121
}
saltLength := opts.saltLength()
if fips140only.Enforced() && saltLength > h.Size() {
return nil, errors.New("crypto/rsa: use of PSS salt longer than the hash is not allowed in FIPS 140-only mode")
}
switch saltLength {
case PSSSaltLengthAuto:
saltLength, err = rsa.PSSMaxSaltLength(k.PublicKey(), h)
if err != nil {
return nil, fipsError(err)
}
case PSSSaltLengthEqualsHash:
saltLength = h.Size()
default:
// If we get here saltLength is either > 0 or < -1, in the
// latter case we fail out.
if saltLength <= 0 {
return nil, errors.New("crypto/rsa: invalid PSS salt length")
}
}
return fipsError2(rsa.SignPSS(random, k, h, digest, saltLength))
}
// VerifyPSS verifies a PSS signature.
//
// A valid signature is indicated by returning a nil error. digest must be the
// result of hashing the input message using the given hash function. The opts
// argument may be nil, in which case sensible defaults are used. opts.Hash is
// ignored.
//
// The inputs are not considered confidential, and may leak through timing side
// channels, or if an attacker has control of part of the inputs.
func VerifyPSS(pub *PublicKey, hash crypto.Hash, digest []byte, sig []byte, opts *PSSOptions) error {
if err := checkPublicKeySize(pub); err != nil {
return errView on GitHub (pinned to b6b368adc5)
Solutions
- Use rsa.PSSSaltLengthEqualsHash (-1) or rsa.PSSSaltLengthAuto (0) instead of custom negative values.
- If you need an explicit length, ensure it is a positive integer greater than zero.
- Validate opts.SaltLength before calling SignPSS if the value comes from untrusted/config input.
Example fix
// before
opts := &rsa.PSSOptions{SaltLength: configSalt /* accidentally -2 */}
sig, err := rsa.SignPSS(rand.Reader, priv, crypto.SHA256, digest, opts)
// after
if opts.SaltLength < -1 || (opts.SaltLength < 0 && opts.SaltLength != rsa.PSSSaltLengthEqualsHash) {
opts.SaltLength = rsa.PSSSaltLengthEqualsHash
}
sig, err := rsa.SignPSS(rand.Reader, priv, crypto.SHA256, digest, opts) Defensive patterns
Strategy: validation
Validate before calling
func validatePSSSaltLength(opts *rsa.PSSOptions) error {
if opts == nil {
return nil
}
sl := opts.SaltLength
if sl == rsa.PSSSaltLengthAuto || sl == rsa.PSSSaltLengthEqualsHash {
return nil
}
if sl <= 0 {
return fmt.Errorf("invalid PSS salt length %d: use PSSSaltLengthAuto, PSSSaltLengthEqualsHash, or a positive int", sl)
}
return nil
}
if err := validatePSSSaltLength(opts); err != nil { return err } Type guard
func isValidSaltLength(sl int) bool {
return sl == rsa.PSSSaltLengthAuto ||
sl == rsa.PSSSaltLengthEqualsHash ||
sl > 0
} Prevention
- Never use arbitrary negative sentinels for PSS salt length — only 0 and -1 are defined.
- When loading salt length from config, coerce unknown/missing values to PSSSaltLengthEqualsHash rather than passing them through.
- Unit-test the PSS options construction with a table of salt-length values.
When it happens
Trigger: Passing &rsa.PSSOptions{SaltLength: -2} (or any value < -1) to SignPSS. A zero-value PSSOptions does NOT trip this because SaltLength 0 == PSSSaltLengthAuto which is handled. An uninitialized *int from a config struct that defaults to a negative sentinel accidentally can trip it.
Common situations: Config file maps a missing salt-length field to -1 as 'not set' but -1 is actually PSSSaltLengthEqualsHash; a separate 'disabled' code path uses -2 and hits validation. Off-by-one arithmetic on salt length producing a negative result.
Related errors
- crypto/rsa: invalid PSS salt length
- crypto/rsa: use of PSS salt longer than the hash is not allo
- crypto/rsa: input must be hashed message
- crypto/rsa: verification error
- crypto/rsa: unsupported hash function: %d
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/549ccee3747850bf.
Report an issue: GitHub.