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

  1. Align the Beam Go SDK version with the runner/job-service version
  2. Log the full msg.String() content shown in the error to identify the unknown message type
  3. Pin container/runner images to compatible Beam versions
  4. 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

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


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/0d44b5b9e424e1d8. Report an issue: GitHub.