hyperledger/fabric · error

Attempted to set the batch timeout to a non-positive value:

Error message

Attempted to set the batch timeout to a non-positive value: %s

What it means

After successfully parsing the duration, validateBatchTimeout rejects non-positive values. A batch timeout of zero or negative would make the orderer cut batches immediately or behave nonsensically, so the config is rejected.

Source

Thrown at common/channelconfig/orderer.go:237

		return fmt.Errorf("Attempted to set the batch size absolute max bytes to an invalid value: 0")
	}
	if oc.protos.BatchSize.PreferredMaxBytes == 0 {
		return fmt.Errorf("Attempted to set the batch size preferred max bytes to an invalid value: 0")
	}
	if oc.protos.BatchSize.PreferredMaxBytes > oc.protos.BatchSize.AbsoluteMaxBytes {
		return fmt.Errorf("Attempted to set the batch size preferred max bytes (%v) greater than the absolute max bytes (%v).", oc.protos.BatchSize.PreferredMaxBytes, oc.protos.BatchSize.AbsoluteMaxBytes)
	}
	return nil
}

func (oc *OrdererConfig) validateBatchTimeout() error {
	var err error
	oc.batchTimeout, err = time.ParseDuration(oc.protos.BatchTimeout.Timeout)
	if err != nil {
		return fmt.Errorf("Attempted to set the batch timeout to a invalid value: %s", err)
	}
	if oc.batchTimeout <= 0 {
		return fmt.Errorf("Attempted to set the batch timeout to a non-positive value: %s", oc.batchTimeout)
	}
	return nil
}

func (oc *OrdererConfig) validateAllOrgsHaveEndpoints() error {
	var orgsMissingEndpoints []string

	for _, org := range oc.Organizations() {
		if len(org.Endpoints()) == 0 {
			orgsMissingEndpoints = append(orgsMissingEndpoints, org.Name())
		}
	}

	if len(orgsMissingEndpoints) > 0 {
		return errors.Errorf("some orderer organizations endpoints are empty: %s", orgsMissingEndpoints)
	}

	return nil

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Set BatchTimeout to a positive duration, e.g. "2s" (Fabric default)
  2. If you want faster block cutting, lower it toward e.g. "250ms" but keep it > 0
  3. Regenerate the config with configtxgen

Example fix

# before (configtx.yaml)
BatchTimeout: 0s
# after
BatchTimeout: 2s
Defensive patterns

Strategy: validation

Validate before calling

d, err := time.ParseDuration(cfg.Orderer.BatchTimeout)
if err != nil || d <= 0 {
	return fmt.Errorf("BatchTimeout must be a positive duration, got %q", cfg.Orderer.BatchTimeout)
}

Try / catch

if err != nil && strings.Contains(err.Error(), "non-positive value") {
	return fmt.Errorf("set BatchTimeout > 0 (Fabric default 2s): %w", err)
}

Prevention

When it happens

Trigger: BatchTimeout set to "0s", "-1s", or "0" (with valid unit) in configtx.yaml or in a channel config update transaction.

Common situations: Copying example configs and setting BatchTimeout to 0 to "disable" batching (misunderstanding it as a disable switch); template variables defaulting to zero values; scripting that computes the timeout and passes 0 or a negative.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/9c54ba26075b2e35. Report an issue: GitHub.