hyperledger/fabric · error
envelope timestamp %s is more than %s apart from current ser
Error message
envelope timestamp %s is more than %s apart from current server time %s
What it means
validateChannelHeader compares the envelope timestamp to server time; if the absolute difference exceeds the handler's configured TimeWindow the request is rejected. This prevents replaying old SeekInfo envelopes and bounds clock-skew-sensitive authorization (context binding).
Source
Thrown at common/deliver/deliver.go:401
err = h.validateChannelHeader(ctx, chdr)
if err != nil {
return nil, nil, nil, err
}
return payload, chdr, shdr, nil
}
func (h *Handler) validateChannelHeader(ctx context.Context, chdr *cb.ChannelHeader) error {
if chdr.GetTimestamp() == nil {
err := errors.New("channel header in envelope must contain timestamp")
return err
}
envTime := time.Unix(chdr.GetTimestamp().Seconds, int64(chdr.GetTimestamp().Nanos)).UTC()
serverTime := time.Now()
if math.Abs(float64(serverTime.UnixNano()-envTime.UnixNano())) > float64(h.TimeWindow.Nanoseconds()) {
err := errors.Errorf("envelope timestamp %s is more than %s apart from current server time %s", envTime, h.TimeWindow, serverTime)
return err
}
err := h.BindingInspector.Inspect(ctx, chdr)
if err != nil {
return err
}
return nil
}
func noExpiration(_ []byte) time.Time {
return time.Time{}
}
View on GitHub (pinned to 2736b63f8f)
Solutions
- Synchronize the client machine's clock with NTP (chrony/ntpd or host time sync for containers).
- Re-sign and send the deliver request immediately before dispatch, not ahead of time.
- Increase the orderer's deliver TimeWindow configuration if the deployment legitimately tolerates larger skew.
- Compare client clock to orderer (e.g. orderer health/log timestamps) to quantify the skew.
Example fix
// before (client signs at script start, sends later) timestamp := scriptStartTime // after (sign just before send, with synced clock) runNtpSync() timestamp := protoutil.CurrentTimestampBytes() env, _ := protoutil.CreateEnvelope(...); deliverNow(env)
Defensive patterns
Strategy: retry
Validate before calling
skew := time.Since(time.Unix(chdr.GetTimestamp().Seconds, int64(chdr.GetTimestamp().Nanos)).UTC())
if skew < 0 { skew = -skew }
if skew > 15*time.Minute { resyncClockAndResignEnvelope() } Try / catch
for attempt := 0; attempt < 2; attempt++ {
err := sendDeliverRequest(env)
if err != nil && strings.Contains(err.Error(), "apart from current server time") {
syncClock(); env = resignWithFreshTimestamp(); continue
}
return err
} Prevention
- Run NTP (chrony/ntpd) on all hosts and containers that sign deliver requests
- Sign deliver envelopes immediately before sending
- Monitor clock drift against orderer timestamps in health checks
- Only widen orderer deliver TimeWindow deliberately and document it
When it happens
Trigger: Client clock is off (ahead or behind) by more than TimeWindow (default 15m) when the deliver request is signed and sent; a delayed/queued request that exceeds the window; a replayed captured envelope.
Common situations: VMs/containers with drifting clocks and no NTP; signing a request long before sending (batch scripts); cross-timezone/local-time bugs when computing timestamps in custom clients.
Related errors
- channel header in envelope must contain timestamp
- envelope has no header
- wrong chain type
- error getting private data by block number %d
- channel %s not found
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/daadd619817238c1.
Report an issue: GitHub.