nautechsystems/nautilus_trader · error · anyhow::Error

Binance Futures GTD cannot be post-only

Error message

Binance Futures GTD cannot be post-only

What it means

Binance Futures rejects a native GTD (goodTillDate) order that is also post-only; the two constraints cannot be combined at the venue. The adapter enforces this client-side in determine_futures_order_lifetime so the order fails fast with a clear message instead of an exchange rejection.

Solutions

  1. Drop post_only on GTD orders (post_only=false) if the expiry is required.
  2. Keep post_only and switch time_in_force to Gtc.
  3. Set use_gtd=false (or manage_gtd_expiry locally) so the GTD is emulated client-side as GTC with a local cancel, preserving post-only.
  4. Split configuration: post-only orders use GTC, expiring orders skip post-only.

Example fix

// before
order_factory.limit(..., TimeInForce::Gtd, Some(expire), post_only=true);
// after
order_factory.limit(..., TimeInForce::Gtc, None, post_only=true); // or post_only=false with GTD
Defensive patterns

Strategy: validation

Validate before calling

if tif == TimeInForce::Gtd && use_gtd && post_only {
    // choose: post_only + Gtc, or GTD without post_only
}

Prevention

When it happens

Trigger: validate_order / build_futures_order_list_batch with TimeInForce=Gtd, use_gtd=true, and post_only=true on a Limit (or limit-style) order.

Common situations: Maker-only strategies using post-only limit orders while a global GTD expiry is configured; combining a default expire_time with the adapter's post-only flag without realizing the venue disallows the pair.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/c7dc82faff8bd6a3. Report an issue: GitHub.

Appendix: source

Thrown at crates/adapters/binance/src/futures/execution.rs:1501

    if !use_gtd {
        log::warn!(
            "Binance Futures GTD submitted as GTC because use_gtd=false. Enable manage_gtd_expiry on the submitting strategy"
        );
        return Ok(FuturesOrderLifetime {
            time_in_force: TimeInForce::Gtc,
            good_till_date: None,
        });
    }

    anyhow::ensure!(
        matches!(
            order_type,
            OrderType::Limit | OrderType::StopLimit | OrderType::LimitIfTouched
        ),
        "Binance Futures does not support GTD for order type {order_type:?}"
    );
    anyhow::ensure!(!post_only, "Binance Futures GTD cannot be post-only");

    anyhow::ensure!(
        product_type == BinanceProductType::UsdM,
        "Binance {product_type:?} Futures does not support native GTD"
    );

    let expire_time = expire_time.context("Binance Futures GTD requires an expire_time")?;
    let expire_ns = expire_time.as_u64();
    anyhow::ensure!(
        expire_ns.is_multiple_of(NANOSECONDS_IN_SECOND),
        "Binance Futures goodTillDate requires whole-second precision"
    );

    let minimum_ns = ts_now
        .as_u64()
        .checked_add(BINANCE_GTD_MIN_LEAD_SECS * NANOSECONDS_IN_SECOND)
        .context("Binance Futures GTD minimum timestamp overflow")?;
    anyhow::ensure!(

View on GitHub (pinned to 18893faf8b)