gofr-dev/gofr · error

token file is empty

Error message

token file is empty

What it means

errEmptyTokenFile is returned by readToken in pkg/gofr/service/file_token_auth.go:24 when the bearer-token file (default /var/run/secrets/kubernetes.io/serviceaccount/token) exists but its contents are empty after trimming whitespace. FileTokenAuthConfig reads the token eagerly at construction so misconfiguration fails at startup rather than on the first upstream call, and a service-account token can never legitimately be blank.

Source

Thrown at pkg/gofr/service/file_token_auth.go:24

	"fmt"
	"net/http"
	"os"
	"strings"
	"sync"
	"time"

	"gofr.dev/pkg/gofr/logging"
)

const (
	// DefaultTokenFilePath is the standard Kubernetes projected service account token mount path.
	DefaultTokenFilePath = "/var/run/secrets/kubernetes.io/serviceaccount/token" // #nosec G101 -- file path, not a credential

	defaultRefreshInterval = 30 * time.Second
)

var (
	errEmptyTokenFile    = errors.New("token file is empty")
	errTokenUnavailable  = errors.New("no token available")
	errAuthHeaderPresent = errors.New("authorization header already set on request")
)

// FileTokenAuthConfig reads a bearer token from a local file and periodically
// re-reads it to support token rotation (e.g. Kubernetes projected service
// account tokens).
//
// The returned value implements Options, Observable and
// io.Closer. Call Close to stop the background refresh goroutine; it is safe
// to call Close multiple times.
type FileTokenAuthConfig struct {
	tokenFilePath   string
	refreshInterval time.Duration

	logger logging.Logger

	mu    sync.RWMutex

View on GitHub (pinned to 187eb24962)

Solutions

  1. Ensure the token file actually contains a service-account JWT (cat the path; it must be non-empty) and that the pod mounts the projected volume correctly.
  2. If the path is wrong, pass WithTokenFilePath("/correct/path/token") to NewFileTokenAuthConfig.
  3. If a failed rotation truncated the file, remount/recreate the projected volume (or restart the pod) so kubelet rewrites the token.
  4. In local/dev environments, generate a real token file instead of an empty stub.

Example fix

// before
f, err := service.NewFileTokenAuthConfig() // empty /var/run/.../token outside K8s
// after
f, err := service.NewFileTokenAuthConfig(service.WithTokenFilePath("/tmp/dev-sa-token"))
Defensive patterns

Strategy: validation

Validate before calling

data, err := os.ReadFile(tokenPath)
if err != nil { return err }
if len(strings.TrimSpace(string(data))) == 0 { return errors.New("token file is empty: " + tokenPath) }

Type guard

func hasToken(path string) bool {
	b, err := os.ReadFile(path)
	return err == nil && len(strings.TrimSpace(string(b))) > 0
}

Prevention

When it happens

Trigger: Calling NewFileTokenAuthConfig (or any options wrapper) when the file at tokenFilePath exists but contains only whitespace/an empty string; also raised by the background refreshLoop and logged as a WARN when the projected volume empties mid-run.

Common situations: Mounting the Kubernetes projected service-account token with an unset serviceAccountToken audience/path so the file is created empty; pointing WithTokenFilePath at a manually created placeholder file; a secret or volume that has been truncated by a failed rotation; running locally outside K8s with an empty stub file.

Related errors


AI-assisted analysis of gofr-dev/gofr@187eb24962 (2026-09-01). Data as JSON: /api/errors/ce80a6d445d50ecc. Report an issue: GitHub.