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
- Fix the client to populate the SessionResponse/Request oneof with InitializeSession before sending the initial handshake.
- Verify client and server kopia versions are compatible (same grpcapi protocol).
- Check that no intermediate proxy is altering or dropping the request payload.
- 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
- Always populate the InitializeSession oneof in the initial gRPC request.
- Keep client and server on matching kopia versions.
- Add protocol-level integration tests for the handshake.
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
- InitializeSession must be the first request in a session
- unhandled session request
- unable to read initialization request
- did not receive response from the server
- error connecting to API server
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)