grpc/grpc-go · error

token file access error

Error message

token file access error

What it means

errTokenFileAccess is the sentinel error returned by the JWT file reader when os.ReadFile fails on the configured token file path. The actual OS-level error (permission denied, file not found, etc.) is wrapped inside, so callers can unwrap it to diagnose the filesystem problem. This is used by JWT-based per-RPC credentials that read a token (and its expiration) from a file on every RPC or on refresh.

Solutions

  1. Verify the token file path is absolute and correct; check it exists with ls -l from the same process context.
  2. Ensure the process user has read permission on the file (chmod/chown, or runAsUser in Kubernetes).
  3. If using Kubernetes projected tokens, confirm the volumeMount and volume are configured and the pod has started successfully.
  4. Unwrap the error with errors.Unwrap or fmt.Errorf(%w) logging to see the underlying OS error.

Example fix

// before
tokenPath := "/var/run/secrets/token" // wrong path or missing mount
reader := newJWTFileReader(tokenPath)
// after
tokenPath := "/var/run/secrets/tokens/gcp-sa-token" // verified path
// also ensure Kubernetes volumeMount is present:
// volumeMounts:
// - name: token
//   mountPath: /var/run/secrets/tokens
//   readOnly: true
Defensive patterns

Strategy: try-catch

Validate before calling

// Check file exists and is readable before creating the credential:
if info, err := os.Stat(tokenPath); err != nil || info.IsDir() {
    return fmt.Errorf("token file %q not accessible: %w", tokenPath, err)
}

Try / catch

token, exp, err := reader.readToken()
if err != nil {
    if errors.Is(err, errTokenFileAccess) {
        // log underlying OS error, alert ops team
    }
    return err
}

Prevention

When it happens

Trigger: The jwtFileReader.readToken method calls os.ReadFile(r.tokenFilePath) and it fails. Common failure causes: the path is wrong, the file does not exist, the process lacks read permission, or the path points to a directory. Also triggered when a mounted secret volume (e.g., Kubernetes service-account token) is not yet available.

Common situations: Kubernetes pods where the projected service-account token path changed or the volume mount is delayed. Containers running as a user without read access to the token file. Configuration typos in the token file path (absolute vs relative). Rotating-token setups where the file is briefly absent during rotation.

Related errors


AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11). Data as JSON: /api/errors/2eafd600d5ecddac. Report an issue: GitHub.

Appendix: source

Thrown at credentials/jwt/file_reader.go:32

 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package jwt

import (
	"encoding/base64"
	"encoding/json"
	"errors"
	"fmt"
	"os"
	"strings"
	"time"
)

var (
	errTokenFileAccess = errors.New("token file access error")
	errJWTValidation   = errors.New("invalid JWT")
)

// jwtClaims represents the JWT claims structure for extracting expiration time.
type jwtClaims struct {
	Exp int64 `json:"exp"`
}

// jwtFileReader handles reading and parsing JWT tokens from files.
// It is safe to call methods on this type concurrently as no state is stored.
type jwtFileReader struct {
	tokenFilePath string
}

// readToken reads and parses a JWT token from the configured file.
// Returns the token string, expiration time, and any error encountered.
func (r *jwtFileReader) readToken() (string, time.Time, error) {
	tokenBytes, err := os.ReadFile(r.tokenFilePath)

View on GitHub (pinned to 0c51461d27)