# rpc error: code = Unauthenticated desc = token expired: current time 2025-01-15T10:00:00Z is after exp 2025-01-15T09:00:00Z

- **ID:** `go/grpc-unauthenticated-token-expired`
- **Domain:** go
- **Category:** auth_error
- **Verification:** ai_generated
- **Fix Rate:** 80%

## Root Cause

The authentication token used in the gRPC call has expired, requiring a new token.

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| 1.0 | active | — | — |
| 1.1 | active | — | — |

## Workarounds

1. **Refresh the token before making the RPC call.** (90% success)
   ```
   token, err := refreshToken()
if err != nil { log.Fatal(err) }
conn, err := grpc.Dial("localhost:8080", grpc.WithInsecure(), grpc.WithPerRPCCredentials(&tokenCreds{token: token}))
   ```
2. **Implement automatic token refresh in an interceptor.** (85% success)
   ```
   func refreshInterceptor(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
    token, err := getValidToken()
    if err != nil { return err }
    md := metadata.Pairs("authorization", "Bearer "+token)
    ctx = metadata.NewOutgoingContext(ctx, md)
    return invoker(ctx, method, req, reply, cc, opts...)
}
   ```

## Dead Ends

- **Use the same expired token and hope it works.** — The server checks expiration; expired tokens are always rejected. (100% fail)
- **Manually extend the token's expiration without re-authentication.** — Token expiration is enforced by the auth server; manual changes are invalid. (95% fail)
