grpc/grpc-go · warning
no error details for status with code OK
Error message
no error details for status with code OK
What it means
Returned by Status.WithDetails when the Status has code OK. gRPC's status invariant dictates that an OK status represents success and must never carry error details (details are rich metadata for failures). WithDetails explicitly rejects adding details to an OK status to prevent creating a semantically contradictory state. Details are only meaningful attached to non-OK codes.
Solutions
- Only call WithDetails when the status code is not OK: check st.Code() != codes.OK first.
- Construct the status with a non-OK code before adding details: status.New(codes.InvalidArgument, "bad input").
- Refactor shared code to guard the WithDetails call with a code check.
- If you need metadata on a successful response, use response headers/trailers, not status details.
Example fix
// before
st := status.New(codes.OK, "success")
st, err := st.WithDetails(detail) // error!
// after
st := status.New(codes.InvalidArgument, "invalid input")
st, err := st.WithDetails(detail) // ok
// or guard:
if st.Code() != codes.OK {
st, _ = st.WithDetails(detail)
} Defensive patterns
Strategy: validation
Validate before calling
// Only call WithDetails on non-OK statuses.
func safeWithDetails(st *status.Status, details ...protoadapt.MessageV1) (*status.Status, error) {
if st.Code() == codes.OK {
return st, nil // no details for success
}
return st.WithDetails(details...)
} Try / catch
st, err := st.WithDetails(detail)
if err != nil && strings.Contains(err.Error(), "code OK") {
// programming error: don't add details to OK status
log.Print("warning: attempted to add details to OK status")
} Prevention
- Check st.Code() != codes.OK before calling WithDetails.
- Only construct statuses with non-OK codes when you intend to add details.
- Use response metadata/headers for successful-response metadata instead of status details.
- Review interceptors that wrap statuses to ensure they guard WithDetails calls.
When it happens
Trigger: Calling st.WithDetails(detailProto) on a Status created with status.New(codes.OK, "") or obtained from a successful RPC. This is a programming error—the caller should only attach details to failure statuses.
Common situations: Interceptor or handler code that attaches details unconditionally without checking the code; error-wrapping utilities that call WithDetails on whatever status they receive, including success; copy-paste from error-handling code into a success path.
Related errors
- buffer size is not an exponent of two
- cannot have a leading slash
- cannot have exclude and a '*' wildcard
- credentials: audience cannot be empty
- credentials: ctx cannot be nil
AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11).
Data as JSON: /api/errors/e7d639db318e5ceb.
Report an issue: GitHub.
Appendix: source
Thrown at internal/status/status.go:136
if s == nil {
return nil
}
return proto.Clone(s.s).(*spb.Status)
}
// Err returns an immutable error representing s; returns nil if s.Code() is OK.
func (s *Status) Err() error {
if s.Code() == codes.OK {
return nil
}
return &Error{s: s}
}
// WithDetails returns a new status with the provided details messages appended to the status.
// If any errors are encountered, it returns nil and the first error encountered.
func (s *Status) WithDetails(details ...protoadapt.MessageV1) (*Status, error) {
if s.Code() == codes.OK {
return nil, errors.New("no error details for status with code OK")
}
// s.Code() != OK implies that s.Proto() != nil.
p := s.Proto()
for _, detail := range details {
m, err := anypb.New(protoadapt.MessageV2Of(detail))
if err != nil {
return nil, err
}
p.Details = append(p.Details, m)
}
return &Status{s: p}, nil
}
// Details returns a slice of details messages attached to the status.
// If a detail cannot be decoded, the error is returned in place of the detail.
// If the detail can be decoded, the proto message returned is of the same
// type that was given to WithDetails().
func (s *Status) Details() []any {View on GitHub (pinned to 0c51461d27)