{"record":{"id":"7b7eae9c4475024f","repo":"amir20/dozzle","slug":"unknown-error-v-with-w","errorCode":null,"errorMessage":"unknown error: %v with %w","messagePattern":"unknown error: (.+?) with %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/agent/client.go","lineNumber":127,"sourceCode":"\t\treturn nil\n\t}\n\n\tstatus, ok := status.FromError(err)\n\tif !ok {\n\t\treturn err\n\t}\n\n\tif status.Code() == codes.Unknown && status.Message() == \"EOF\" {\n\t\treturn fmt.Errorf(\"EOF error while converting gRPC to error: %w\", io.EOF)\n\t}\n\n\tswitch status.Code() {\n\tcase codes.Canceled:\n\t\treturn fmt.Errorf(\"canceled: %v with %w\", status.Message(), context.Canceled)\n\tcase codes.DeadlineExceeded:\n\t\treturn fmt.Errorf(\"deadline exceeded: %v with %w\", status.Message(), context.DeadlineExceeded)\n\tcase codes.Unknown:\n\t\treturn fmt.Errorf(\"unknown error: %v with %w\", status.Message(), err)\n\tcase codes.OK:\n\t\treturn nil\n\tdefault:\n\t\treturn fmt.Errorf(\"unknown code: %v with %w\", status.Code(), err)\n\t}\n}\n\nfunc (c *Client) LogsBetweenDates(ctx context.Context, containerID string, since time.Time, until time.Time, std container.StdType) (<-chan *container.LogEvent, error) {\n\tstream, err := c.client.LogsBetweenDates(ctx, &pb.LogsBetweenDatesRequest{\n\t\tContainerId: containerID,\n\t\tSince:       timestamppb.New(since),\n\t\tUntil:       timestamppb.New(until),\n\t\tStreamTypes: int32(std),\n\t})\n\n\tif err != nil {\n\t\treturn nil, err\n\t}","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/amir20/dozzle/blob/d9463cbe21874e44ab79db6fa63e746ca7d22928/internal/agent/client.go#L109-L145","documentation":"rpcErrToErr maps gRPC status code Unknown (with a message other than \"EOF\") to \"unknown error: %v with %w\", wrapping the original status error. This is the catch-all for server-side errors returned without a specific gRPC code, usually panics or plain Go errors from the agent handler.","triggerScenarios":"Any agent RPC whose server handler returned an unclassified error (a plain Go error via status.Unknown or a panic recovered by gRPC), e.g. Docker API failures inside the agent.","commonSituations":"Agent failing to reach the local Docker socket (permission denied on /var/run/docker.sock); Docker API errors while listing containers or reading logs; version mismatch causing unhandled proto fields; agent panics on unexpected input.","solutions":["Read the wrapped status message (`status.Convert(err).Message()`) to find the root cause, and check agent container logs at the same time","Fix the underlying agent-side condition (e.g. mount /var/run/docker.sock with correct permissions in the agent container)","Ensure agent and server run the same Dozzle version to avoid protocol mismatches","File/report a panic if the message contains a stack trace; unclassified errors should map to specific codes"],"exampleFix":"// before\nif err := <-errCh; err != nil { log.Error().Msg(\"agent call failed\") }\n// after\nif err := <-errCh; err != nil {\n    if st, ok := status.FromError(errors.Unwrap(err)); ok {\n        log.Error().Str(\"grpc_msg\", st.Message()).Msg(\"agent call failed\")\n    }\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err != nil {\n    if st, ok := status.FromError(errors.Unwrap(err)); ok {\n        log.Error().Str(\"code\", st.Code().String()).Str(\"msg\", st.Message()).Msg(\"agent error\")\n    }\n}","preventionTips":["Check agent container logs; Unknown errors mirror unclassified agent-side failures (usually Docker socket access)","Keep agent and server on the same version","Mount /var/run/docker.sock into the agent with correct permissions"],"tags":["go","grpc","agent","docker"],"backgroundTag":"grpc-unknown-status-error","analyzedSha":"d9463cbe21874e44ab79db6fa63e746ca7d22928","analyzedAt":"2026-09-07T10:08:55.855Z","contentChangedAt":"2026-09-07T10:08:55.855Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}