apache/beam · error
unexpected job update: %v
Error message
unexpected job update: %v
What it means
WaitForCompletion processes a stream of job update messages of several known kinds (messages, state changes, metrics). If a message arrives whose type does not match any handled case, the universal runner aborts with 'unexpected job update: %v', including the protobuf message's String() form. It indicates a protocol mismatch between client and job service.
Source
Thrown at sdks/go/pkg/beam/runners/universal/runnerlib/job.go:163
}
if resp.GetMessageId() != "" {
fmt.Fprintf(&b, "(id=%v)", resp.GetMessageId())
}
b.WriteString(resp.GetMessageText())
text := b.String()
log.Output(ctx, messageSeverity(resp.GetImportance()), 1, text)
if resp.GetImportance() >= jobpb.JobMessage_JOB_MESSAGE_ERROR {
errReceived = true
mostRecentError = resp.GetMessageText()
if jobFailed {
return errors.Errorf("job %v failed:\n%w", jobID, errors.New(mostRecentError))
}
}
default:
return errors.Errorf("unexpected job update: %v", msg.String())
}
}
}
func messageSeverity(importance jobpb.JobMessage_MessageImportance) log.Severity {
switch importance {
case jobpb.JobMessage_JOB_MESSAGE_ERROR:
return log.SevError
case jobpb.JobMessage_JOB_MESSAGE_WARNING:
return log.SevWarn
case jobpb.JobMessage_JOB_MESSAGE_BASIC:
return log.SevInfo
case jobpb.JobMessage_JOB_MESSAGE_DEBUG, jobpb.JobMessage_JOB_MESSAGE_DETAILED:
return log.SevDebug
default:
return log.SevUnspecified
}View on GitHub (pinned to 12126d8942)
Solutions
- Align the Beam Go SDK version with the runner/job-service version
- Log the full msg.String() content shown in the error to identify the unknown message type
- Pin container/runner images to compatible Beam versions
- If the message is benign, upgrade Beam — newer client versions handle more update kinds
Example fix
// before
default:
return errors.Errorf("unexpected job update: %v", msg.String())
// after
default:
log.Printf("ignoring unknown job update: %v", msg.String())
// or upgrade the SDK to match the job service version
return errors.Errorf("unexpected job update: %v", msg.String()) Defensive patterns
Strategy: try-catch
Try / catch
if err := runner.WaitForCompletion(ctx, conn, jobID, deadline, printer); err != nil {
if strings.Contains(err.Error(), "unexpected job update") {
log.Printf("protocol mismatch with job service: %v", err)
}
return err
} Prevention
- Pin the Go SDK version to the runner's Beam version
- Upgrade the SDK if the runner was updated to a newer Beam release
- Log full message contents when introducing new runner backends
When it happens
Trigger: Streaming GetJobEvents/GetMessages responses whose oneof variant is not among the cases handled in WaitForCompletion — typically from a newer/older runner server version speaking a slightly different Job API.
Common situations: Version skew between the Beam Go SDK and the remote runner (e.g. Flink/Spanner portable job server updated independently); proxies injecting unexpected message types.
Related errors
- could not detect user main
- job %v failed: %w
- Type interface{} isn't a supported PCollection type
- Iterators with timestamp values (<ET,V> and <ET, K, V>) are
- Type interface{} isn't a supported PCollection type
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/0d44b5b9e424e1d8.
Report an issue: GitHub.