kopia/kopia · error

missing initialization request

Error message

missing initialization request

What it means

During the initial gRPC session handshake, the server reads an initialization request from the client and expects a non-nil InitializeSession payload. If initializeReq.GetInitializeSession() is nil — meaning the client sent a request of a different type or an empty request — the handshake is aborted with this error and no session is created.

Solutions

  1. Fix the client to populate the SessionResponse/Request oneof with InitializeSession before sending the initial handshake.
  2. Verify client and server kopia versions are compatible (same grpcapi protocol).
  3. Check that no intermediate proxy is altering or dropping the request payload.
  4. Capture the gRPC traffic (grpclog) to confirm what the client actually sent.

Example fix

// before: sending an empty request
req := &grpcapi.Request{RequestId: id}
// after
req := &grpcapi.Request{RequestId: id, Request: &grpcapi.Request_InitializeSession{InitializeSession: &grpcapi.InitializeSession{}}}
Defensive patterns

Strategy: try-catch

Validate before calling

// client side: before sending
if req.GetInitializeSession() == nil {
    return errors.New("refusing to send handshake without InitializeSession payload")
}

Type guard

if ir := initializeReq.GetInitializeSession(); ir == nil { /* abort: wrong request type */ }

Try / catch

if err := session.Connect(ctx); err != nil {
    if strings.Contains(err.Error(), "missing initialization request") {
        // fix client protocol payload / upgrade client
    }
}

Prevention

When it happens

Trigger: A gRPC client calls the session initialization RPC (handled by handleInitialSessionHandshake in internal/server/grpc_session.go) with a grpcapi.Request that has no InitializeSession oneof member set, or sends an empty/uninitialized request message.

Common situations: Version mismatch between client and server where the client sends a different handshake message type; a buggy or hand-rolled client that forgets to populate the InitializeSession field; a proxy/middleware that strips or rewrites the request payload.

Understand the failure class

Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.

Related errors


AI-assisted analysis of kopia/kopia@82495e54b5 (2026-09-07). Data as JSON: /api/errors/b74ff85eae9dffcb. Report an issue: GitHub.

Appendix: source

Thrown at internal/server/grpc_session.go:628

func makeEntryMetadata(em *manifest.EntryMetadata) *grpcapi.ManifestEntryMetadata {
	return &grpcapi.ManifestEntryMetadata{
		Id:           string(em.ID),
		Length:       int32(em.Length), //nolint:gosec
		ModTimeNanos: em.ModTime.UnixNano(),
		Labels:       em.Labels,
	}
}

func (s *Server) handleInitialSessionHandshake(srv grpcapi.KopiaRepository_SessionServer, dr repo.DirectRepository) (repo.WriteSessionOptions, error) {
	initializeReq, err := srv.Recv()
	if err != nil {
		return repo.WriteSessionOptions{}, errors.Wrap(err, "unable to read initialization request")
	}

	ir := initializeReq.GetInitializeSession()
	if ir == nil {
		return repo.WriteSessionOptions{}, errors.New("missing initialization request")
	}

	scc := dr.ContentReader().SupportsContentCompression()

	if err := s.send(srv, initializeReq.GetRequestId(), &grpcapi.SessionResponse{
		Response: &grpcapi.SessionResponse_InitializeSession{
			InitializeSession: &grpcapi.InitializeSessionResponse{
				Parameters: &grpcapi.RepositoryParameters{
					HashFunction:               dr.ContentReader().ContentFormat().GetHashFunction(),
					HmacSecret:                 dr.ContentReader().ContentFormat().GetHmacSecret(),
					Splitter:                   dr.ObjectFormat().Splitter,
					SupportsContentCompression: scc,
				},
			},
		},
	}); err != nil {
		return repo.WriteSessionOptions{}, errors.Wrap(err, "unable to send response")
	}

View on GitHub (pinned to 82495e54b5)