Skip to content

fix: support string duration values in JSON/YAML config files#21468

Open
crawfordxx wants to merge 1 commit intoetcd-io:mainfrom
crawfordxx:fix-duration-json-unmarshal
Open

fix: support string duration values in JSON/YAML config files#21468
crawfordxx wants to merge 1 commit intoetcd-io:mainfrom
crawfordxx:fix-duration-json-unmarshal

Conversation

@crawfordxx
Copy link

Summary

  • Fix watch-progress-notify-interval and all other time.Duration config fields failing to unmarshal from string values (e.g. "1m", "500ms") in JSON/YAML config files
  • Add preprocessDurationFields() that converts string duration values to nanosecond integers before unmarshaling, matching the behavior of command-line flags
  • Applies to all 11 duration fields: backend-batch-interval, grpc-keepalive-min-time, grpc-keepalive-interval, grpc-keepalive-timeout, corrupt-check-time, compact-hash-check-time, compaction-sleep-interval, watch-progress-notify-interval, warning-apply-duration, warning-unary-request-duration, downgrade-check-time

Fixes #20342

Root Cause

time.Duration is an int64 in Go and does not implement json.Unmarshaler. When sigs.k8s.io/yaml converts YAML to JSON then uses encoding/json, string values like "1m" cannot be unmarshaled into time.Duration fields. Only raw nanosecond integers work, which is not user-friendly.

Solution

Before passing config bytes to yaml.Unmarshal, pre-process known duration field keys: if the value is a string, parse it with time.ParseDuration and replace it with the equivalent nanosecond integer. Numeric values pass through unchanged.

This approach is minimally invasive - it does not change the Config struct's public API or field types, and follows the existing pattern of translating config file values in configFromFile (similar to how URL string fields are handled).

Test plan

  • Unit test: string duration value for watch-progress-notify-interval parses correctly
  • Unit test: numeric duration value (nanoseconds) still works
  • Unit test: all 11 duration fields parse correctly from strings
  • Unit test: invalid duration string returns error
  • Unit test: preprocessDurationFields handles string, numeric, non-duration, and invalid inputs
  • All existing embed package tests pass

@k8s-ci-robot
Copy link

Hi @crawfordxx. Thanks for your PR.

I'm waiting for a etcd-io member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work.

Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@k8s-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: crawfordxx
Once this PR has been reviewed and has the lgtm label, please assign ahrtr for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

time.Duration fields like watch-progress-notify-interval do not
properly unmarshal from JSON strings (e.g. "1m"). This is because
time.Duration is just an int64 and does not implement json.Unmarshaler.

Add preprocessDurationFields() that converts string duration values
to nanosecond integers before YAML/JSON unmarshaling. This applies
to all duration config fields, matching the behavior of command-line
flags which use time.ParseDuration.

Fixes etcd-io#20342

Signed-off-by: majianhan <majianhan@kylinos.cn>
@crawfordxx crawfordxx force-pushed the fix-duration-json-unmarshal branch from 7f6fba3 to c6708a3 Compare March 12, 2026 03:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

--watch-progress-notify-interval doesn't work through JSON config

2 participants