> ## Documentation Index
> Fetch the complete documentation index at: https://docs.istravex.com/llms.txt
> Use this file to discover all available pages before exploring further.

# What stellar-core validates

> Field by field, what the network checks before a transaction lands in a ledger, and what it passes through untouched.

stellar-core is strict about some fields and indifferent to others. It checks every signature, every sequence number and every fee bid, because consensus depends on them. It doesn't check that memo text is UTF-8, it doesn't interpret a muxed account's ID, and it doesn't bound how deep a Soroban authorization tree goes, because nothing in consensus depends on those. An indexer that treats the second kind like the first is trusting data nobody vouched for.

This table is that distinction, field by field. Read the right-hand columns as a to-do list: everything in **What it passes through** is your code's responsibility.

| Field | stellar-core | What it checks | What it passes through | Corpus | Guide |
| - | - | - | - | - | - |
| **Signatures** `TransactionEnvelope.signatures; AccountEntry.signers, thresholds` | ✓ validated | Every signature verifies, the signers' weights meet each operation's threshold, at most 20 signatures, and none is unused. | Nothing: but which signer signed is only a weight, not an identity the ledger records. | `max-length-vectors` | — |
| **Sequence numbers** `Transaction.seqNum` | ✓ validated | The source account's next sequence number, or within the transaction's sequence preconditions. | Nothing. | `fee-bump`, `muxed-payment` | — |
| **Fees** `Transaction.fee, FeeBumpTransaction.fee, feeSource` | ✓ validated | The bid covers the minimum for every operation and the payer can pay it. | The bid is not the charge: FeeCharged is set after apply, net of Soroban refunds. On a fee-bump the payer is the fee source, not the envelope's source. | `fee-bump`, `muxed-payment` | [fees](https://docs.istravex.com/guide/fees.md) · IX003 |
| **Time bounds** `Transaction.cond.timeBounds` | ✓ validated | The ledger's close time falls inside them. | Nothing; but a ledger's close time is the validators' agreed value, not wall-clock time. | `fee-bump`, `muxed-payment` | — |
| **Bounded vectors and strings** `operations<100>, signatures<20>, signers<20>, memo text<28>` | ✓ validated | XDR decoding refuses one element or byte past each maximum. | Unbounded types (ScVec, ScMap, authorization subinvocations) have no XDR maximum: only the transaction size bounds them. | `max-length-vectors`, `over-max-length`, `scval-limits` | [limits](https://docs.istravex.com/guide/limits.md) |
| **Memo text** `Memo.text` | ✗ passed through | At most 28 bytes. | The bytes themselves: any 28 bytes are valid, UTF-8 or not. | `memo-non-utf8` | [untrusted-strings](https://docs.istravex.com/guide/untrusted-strings.md) · IX001 |
| **Muxed account IDs** `MuxedAccount.med25519.id` | ✗ passed through | Nothing about the ID: the account behind it is checked as if unmuxed. | Any uint64, up to 2^64 − 1, never interpreted. The M… form is not an account: participants and balances belong to the G… account. | `muxed-payment`, `muxed-max-id`, `muxed-soroban-source` | [muxed-accounts](https://docs.istravex.com/guide/muxed-accounts.md) · IX001, IX003 |
| **Soroban authorization trees** `InvokeHostFunctionOp.auth[].rootInvocation.subInvocations` | ◐ partly | Each call that requires authorization must be authorized by a matching entry (signature, nonce, expiry). | The tree's shape: depth and width are bounded only by the transaction size (132,096 bytes on mainnet, November 2026). | `nested-auth` | [bounded-recursion](https://docs.istravex.com/guide/bounded-recursion.md) · IX002 |
| **Contract values** `ScVal, ScMap in arguments, contract data and events` | ◐ partly | Maps are sorted in host order (ScVal type first, then value) with no duplicate keys; the host refuses values deeper than 100 levels. | What the values are. Keys that differ as ScVals (u32 1, symbol "1") can print the same in your language. | `scmap-host-order`, `scval-limits` | [bounded-recursion](https://docs.istravex.com/guide/bounded-recursion.md) · IX002 |
| **Signer keys** `SignerKey (ed25519SignedPayload), AccountEntry.signers` | ◐ partly | The key type, and a payload of 1 to 64 bytes. | The payload's content. A signed-payload signer is a P… strkey of up to 101 bytes, not a 32-byte account key. | `signed-payload-signer` | [signed-payload-signers](https://docs.istravex.com/guide/signed-payload-signers.md) |
| **Liquidity pool assets** `LiquidityPoolConstantProductParameters (assetA, assetB, fee)` | ✓ validated | assetA sorts before assetB in network order (issuer key bytes, not strkey text), and the fee is 30 basis points. | Nothing; but strkey text order is not network order. | `pool-issuer-order` | [addresses](https://docs.istravex.com/guide/addresses.md) |
| **Effects of contract calls** `TransactionMeta.operations[].changes` | ✓ validated | The changes are the consensus result of applying the transaction. | The envelope doesn't say what a contract call did: a trustline created by trust() has no changeTrust operation. | `sac-trust` | [sac-trustlines](https://docs.istravex.com/guide/sac-trustlines.md) |
| **Operations and participants** `Transaction.operations, sourceAccount` | ✓ validated | Each operation is valid for its source when applied. | What the envelope names is what was asked for; the meta says what happened, to which accounts. | `muxed-payment`, `muxed-max-id`, `muxed-soroban-source` | [effects-from-meta](https://docs.istravex.com/guide/effects-from-meta.md) · IX003 |

## How the table stays honest

The table isn't prose that can drift. It's generated from [`kit/guide/fields.json`](https://github.com/hackcat29/istravex/blob/main/kit/guide/fields.json), and CI checks it against the corpus on every commit:

* every pattern a row names has a fixture in the corpus;
* every manifest field a row names is set by one of those fixtures, so each claim has a real value behind it;
* every `expected_decoded` and `expected_indexed` field in the corpus is named by some row, so a new fixture can't add a field nobody classified.

The **Corpus** column names the fixtures where you can see each field on real ledger data. [Fixtures](https://docs.istravex.com/corpus/fixtures.md) lists them all.

## Reading the three verdicts

> [card] ✓ validated
>
> A transaction with a bad value never makes it into a ledger. You can rely on the value, but you may still be reading the wrong one: the fee bid is validated, and it still isn't the fee charged.

> [card] ◐ partly
>
> Some property is enforced and another isn't. Authorization entries must authorize what they claim, but nothing limits how deep the tree goes.

> [card] ✗ passed through
>
> Any value the XDR type allows will appear on the network eventually. Code for the whole range.

> [!TIP]
>
> Reviewed and confirmed by a Stellar Core engineer on 15 November 2026, with [Recommended limits](https://docs.istravex.com/guide/limits.md) and [Addresses and strkeys](https://docs.istravex.com/guide/addresses.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.