amir20/dozzle · error

unknown code: with

Error message

unknown code: %v with %w

What it means

rpcErrToErr's default branch maps any unrecognized gRPC status code to "unknown code: %v with %w", wrapping the original error. It fires when the agent or an intermediary returns a code this client does not explicitly translate (e.g. Unavailable, ResourceExhausted, Internal, PermissionDenied).

Solutions

  1. Inspect the wrapped code (`status.Convert(err).Code()`) and handle common ones: retry with backoff on Unavailable, reduce request size on ResourceExhausted
  2. Add restart/backoff logic keyed on codes.Unavailable, which usually means the agent is temporarily down
  3. Align agent/server versions and regenerate shared certs (`make generate`) if TLS errors appear
  4. Ensure port 7007 is reachable between hosts (firewall, Docker network)

Example fix

// before
if err := <-errCh; err != nil { log.Error().Err(err).Msg("rpc failed") }
// after
if err := <-errCh; err != nil {
    if status, ok := status.FromError(errors.Unwrap(err)); ok && status.Code() == codes.Unavailable {
        time.Sleep(2 * time.Second) // backoff and retry
        return
    }
    log.Error().Err(err).Msg("rpc failed")
}
Defensive patterns

Strategy: retry

Try / catch

if err != nil {
    if st, ok := status.FromError(errors.Unwrap(err)); ok && st.Code() == codes.Unavailable {
        time.Sleep(backoff); retry(); return
    }
    log.Error().Err(err).Msg("rpc failed")
}

Prevention

When it happens

Trigger: Any RPC to the agent returning a non-OK status code other than Canceled, DeadlineExceeded, Unknown, or OK: Unavailable during agent restart, ResourceExhausted on message-size limits, Internal from TLS/transport failures.

Common situations: Agent container restarting while server streams logs (Unavailable); huge log payloads exceeding the 10MB receive limit (ResourceExhausted); TLS cert mismatch causing Internal/Unavailable; firewall dropping the 7007 connection.

Related errors


AI-assisted analysis of amir20/dozzle@d9463cbe21 (2026-09-07). Data as JSON: /api/errors/cc1032b61ef6b544. Report an issue: GitHub.

Appendix: source

Thrown at internal/agent/client.go:131

	if !ok {
		return err
	}

	if status.Code() == codes.Unknown && status.Message() == "EOF" {
		return fmt.Errorf("EOF error while converting gRPC to error: %w", io.EOF)
	}

	switch status.Code() {
	case codes.Canceled:
		return fmt.Errorf("canceled: %v with %w", status.Message(), context.Canceled)
	case codes.DeadlineExceeded:
		return fmt.Errorf("deadline exceeded: %v with %w", status.Message(), context.DeadlineExceeded)
	case codes.Unknown:
		return fmt.Errorf("unknown error: %v with %w", status.Message(), err)
	case codes.OK:
		return nil
	default:
		return fmt.Errorf("unknown code: %v with %w", status.Code(), err)
	}
}

func (c *Client) LogsBetweenDates(ctx context.Context, containerID string, since time.Time, until time.Time, std container.StdType) (<-chan *container.LogEvent, error) {
	stream, err := c.client.LogsBetweenDates(ctx, &pb.LogsBetweenDatesRequest{
		ContainerId: containerID,
		Since:       timestamppb.New(since),
		Until:       timestamppb.New(until),
		StreamTypes: int32(std),
	})

	if err != nil {
		return nil, err
	}

	events := make(chan *container.LogEvent)

	go func() {

View on GitHub (pinned to d9463cbe21)