Skip to content

mpl-core 0.12 + anchor-lang 1.0 — borsh version conflict (E0433 maybestd) blocks Anchor 1.0 migration #282

Description

@alrimarleskovar

Summary

Building a downstream Anchor program that depends on mpl-core 0.12.0 with the anchor feature against anchor-lang 1.0.2 fails with ~400 E0433: failed to resolve: could not find maybestd in borsh errors in mpl-core's generated code (src/generated/types/*.rs, src/generated/accounts/*.rs, src/generated/instructions/*.rs).

This blocks the Agave 2.x / Anchor 1.0 migration for any program that consumes mpl-core via the Anchor helper layer.

Reproduction

Cargo.toml:

[dependencies]
anchor-lang = { version = "1.0.2", features = ["init-if-needed"] }
mpl-core    = { version = "0.12.0", default-features = false, features = ["anchor"] }

cargo build-sbf (or anchor build):

error[E0433]: failed to resolve: could not find `maybestd` in `borsh`
   --> src/generated/accounts/base_asset_v1.rs:NN:NN
    |
NN  |     borsh::maybestd::vec::Vec
    |            ^^^^^^^^ could not find `maybestd` in `borsh`

note: there are multiple different versions of crate `borsh` in the dependency graph
  ...
  one version of crate `borsh` used here, as a direct dependency of the current crate
  one version of crate `borsh` used here, as a dependency of crate `solana_pubkey`

(~400 errors total, all variants of the same maybestd resolution.)

Root cause analysis

  • borsh::maybestd is a no_std compatibility module that existed in borsh 0.10 and was removed in borsh 1.x.
  • mpl-core 0.12's generated code emits borsh::maybestd::* references → expects borsh 0.10's API.
  • anchor-lang 1.0 migrated its internal stack to borsh 1.x. Its transitive solana_pubkey (via Anchor 1.0's solana-program 2.x line) carries borsh 1.x.
  • Cargo unifies the crate name borsh to two incompatible major versions in the same dep graph → trait bounds don't unify → 400 resolution errors.

This is not fixable downstream at the Cargo.toml level. Patching via [patch.crates-io] requires a different source than crates-io (cargo rejects same-source patches), so the only workaround would be patching to a github fork of borsh — more risk surface than the bug.

What we've ruled out (downstream)

Attempt Outcome
mpl-core 0.10 → 0.12 Resolved a separate kaigan zeroize conflict but not this one
default-features = false on mpl-core Resolved the kaigan/anchorkaigan/borsh-v1 mutex but not this one
anchor-lang 0.31.1 → 1.0.2 Closed borsh on Anchor's side; mpl-core still mismatches
IdlBuild impl on custom newtypes (Anchor 0.31+ requirement) Unblocked IDL generation but not the borsh conflict
[patch.crates-io] borsh version pin Cargo rejects same-source patches

Ask

Is mpl-core ↔ Anchor 1.0 compat on the roadmap? If yes, what's a rough ETA we can communicate to our auditor?

If the recommended path is to drop the anchor feature and use the raw mpl-core client, a small example or migration note would be very helpful — we're happy to write up our findings in a doc PR after we land it.

Downstream context

We're a Solana program (ROSCA / behavioral-credit protocol) that uses mpl-core for position NFTs with FreezeDelegate + TransferDelegate plugins. Mainnet GA is gated on the Anchor 1.0 / Agave 2.x migration to land per our auditor's recommendation.

Our migration PR sits in draft tracking the upstream block here:

Happy to provide a minimal repro repo if useful.


Thanks for maintaining mpl-core — it's been a critical primitive for us. Just want to flag this so the migration story can complete cleanly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions