gofiber/fiber · error

decode SHA256 password: invalid length

Error message

decode SHA256 password: invalid length

What it means

Returned by middleware/basicauth when a configured password hash is decoded from base64/hex but the resulting bytes are not exactly sha256.Size (32) long. basicauth accepts "{SHA256}"-prefixed base64, bare hex, or bare base64 SHA-256 digests; any of them must decode to a 32-byte digest or comparison can never match. The length check rejects truncated/corrupted hashes at config time instead of silently failing every login.

Solutions

  1. Regenerate the hash as a 32-byte SHA-256 digest and base64-encode it for the "{SHA256}" form.
  2. If using hex, ensure the full 64-character hex string is present (no truncation).
  3. Use the matching prefix: "{SHA256}" for base64, "{SHA512}" for 64-byte digests.
  4. Verify length programmatically at startup with a config validator.

Example fix

// before
Users: map[string]string{
  "alice": "{SHA256}" + hexdigest, // hex under a base64 prefix
}
// after
import "crypto/sha256","encoding/base64"
sum := sha256.Sum256([]byte("password"))
Users: map[string]string{
  "alice": "{SHA256}" + base64.StdEncoding.EncodeToString(sum[:]),
}
Defensive patterns

Strategy: validation

Validate before calling

func validSHA256(h string) error {
    s := strings.TrimPrefix(h, "{SHA256}")
    b, err := base64.StdEncoding.DecodeString(s)
    if err != nil {
        b, err = hex.DecodeString(s)
        if err != nil { return err }
    }
    if len(b) != sha256.Size {
        return basicauth.ErrInvalidSHA256PasswordLength
    }
    return nil
}

Try / catch

fn, err := basicauth.ValidateUserCreds(...)
if err != nil {
    if errors.Is(err, basicauth.ErrInvalidSHA256PasswordLength) {
        // reject the user config at startup; do not serve with a broken hash
    }
}

Prevention

When it happens

Trigger: Configuring a user with a "{SHA256}<b64>" value whose payload is not 32 bytes, a bare hash string that base64-decodes to the wrong length, or a hex digest that was copy-truncated.

Common situations: Copying a SHA-256 hash from a tool that emitted the hex form but pasting it under the "{SHA256}" base64 convention (or vice versa); truncating the digest in a config file; migrating from SHA-512 hashes without changing the prefix.

Related errors


AI-assisted analysis of gofiber/fiber@a105acad6c (2026-08-11). Data as JSON: /api/errors/c89bd9082f552550. Report an issue: GitHub.

Appendix: source

Thrown at middleware/basicauth/config.go:21

import (
	"crypto/sha256"
	"crypto/sha512"
	"crypto/subtle"
	"encoding/base64"
	"encoding/hex"
	"errors"
	"fmt"
	"sort"
	"strconv"
	"strings"

	"github.com/gofiber/fiber/v3"
	"github.com/gofiber/utils/v2"
	"golang.org/x/crypto/bcrypt"
)

var (
	ErrInvalidSHA256PasswordLength = errors.New("decode SHA256 password: invalid length")
	ErrInvalidSHA512PasswordLength = errors.New("decode SHA512 password: invalid length")
)

// fallbackDummySHA512 is SHA-512("fiber-basicauth-dummy"), used as a
// constant-time comparison target when no users are configured.
var fallbackDummySHA512 = [sha512.Size]byte{
	0x85, 0xc7, 0xd4, 0xbc, 0xec, 0x5f, 0xdf, 0xef, 0xe0, 0x4d, 0xd4, 0x3e, 0xd3, 0xac, 0x45, 0x7c,
	0x5e, 0x48, 0x60, 0x74, 0x12, 0x8e, 0xf8, 0xc0, 0xde, 0x39, 0x89, 0xf9, 0x84, 0x0c, 0x50, 0x24,
	0x1e, 0xa6, 0x1f, 0x2a, 0x11, 0x97, 0xb1, 0xb9, 0x67, 0xa9, 0xf7, 0x3b, 0x82, 0x8f, 0x95, 0xf5,
	0x58, 0xed, 0x3c, 0xab, 0x43, 0x22, 0xf6, 0xfa, 0x84, 0x1d, 0xbc, 0xeb, 0x87, 0xc4, 0x1c, 0x5a,
}

type passwordVerifier func(string) bool

type userVerifiers map[string]passwordVerifier

// Verifier strengths are ordered by expected verification work:
// bcrypt is strongest because it is adaptive and cost-based, SHA-512 follows

View on GitHub (pinned to a105acad6c)