Skip to content
Aug 14, 2026ยท8 min read

What survives an ECC to S/4HANA migration?

An ECC to S/4HANA migration needs an early inventory of Z-programs, exits, BAdIs and hidden dependencies before the 2027 deadline.

What survives an ECC to S/4HANA migration?

The 2027 deadline is not the date to begin an ECC to S/4HANA migration. It is the date by which the difficult decisions, rewrites, rehearsals and business sign-offs need to be finished. The part that derails programmes is rarely the standard SAP conversion. It is the private system built around SAP over twenty years: Z-programs, modified includes, user exits, BAdIs, background jobs, file exchanges, forms, reports and assumptions nobody wrote down.

Treating that estate as a pile of ABAP that merely needs to compile produces a technically green system with broken business behaviour. The assessment must establish four different facts for every object: whether it still runs, whether SAP still permits its extension point, whether anyone still uses it, and whether its output remains correct. Those questions need different evidence. One scan cannot answer all four.

The 2027 date changes the order of work

SAP's published maintenance commitment puts mainstream maintenance for SAP Business Suite 7 core applications through the end of 2027, with optional extended maintenance through the end of 2030 for customers that purchase it. Extended maintenance is breathing room, not a migration design. Procurement can buy support coverage; it cannot buy back the years needed to understand undocumented settlement logic or rebuild a warehouse interface safely.

The sensible first milestone is therefore an evidence-producing assessment, not a target architecture slide. It should leave you with an object inventory, actual usage data, dependency clusters, known simplification impacts, testable business behaviours and named owners. If the assessment produces only a count of custom objects by package, it has counted the problem without describing it.

Start while ECC still represents the truth. Production workload, job history, interface traffic and reconciled financial outputs are far more useful than memories collected after a freeze. Once teams begin switching off jobs or changing integrations for the programme, the baseline becomes contaminated. I have watched teams try to reconstruct old month-end behaviour from meeting notes because nobody captured a clean run when they had the chance. That is avoidable.

The deadline also changes sequencing. Custom-code analysis belongs before a firm conversion scope because the findings can alter the destination. A heavily modified ECC transaction may be a candidate for an S/4HANA extension, a separate service, replacement with standard capability or retirement. You cannot estimate those paths honestly until you know which code and data each transaction touches.

Your custom estate is larger than the Z namespace

A Z-object list is a useful starting point and a dangerous definition of scope. Customer behaviour can live in namespaces, modifications to SAP objects, enhancement implementations, generated code, variants, workflow rules, BRFplus content, forms, job chains, authorisation-dependent branches and external programs that call RFCs or read files. Some of the most consequential code contains no Z transaction that a business owner will recognise.

Build the inventory from several sources and retain the join keys. Repository metadata tells you what exists. ATC and the S/4HANA checks tell you which static patterns collide with the target release. SCMON and SUSG show executed procedures over a representative observation period. ST03N workload data helps connect transactions and users. SM37 job history exposes batch paths. Where modifications exist, SPAU and SPDD history shows the places where the customer diverged from SAP. Interface catalogues, RFC destinations, IDoc configuration and file-transfer schedules cover paths outside dialog usage.

Do not merge these into one risk score too early. Keep at least these fields per object: repository identity, package, component, last change, caller and callee relationships, observed execution, business process, data touched, simplification finding, extension mechanism, test evidence and accountable owner. An object with no observed use may still be a year-end report. A frequently called utility may be low risk because it formats dates. Frequency and consequence are separate axes.

The awkward category is code reached indirectly. A user exit called from standard processing may never appear as a named transaction in workload statistics. A function module may run only through an external RFC. A form routine can be selected by customizing. Dependency analysis must begin at business entry points and traverse calls, tables, messages, jobs and interfaces. Counting isolated objects conceals the clusters that must move together.

I also include operational artifacts in scope. Job variants, printer destinations, logical file paths, event triggers, certificates and technical users are not ABAP, yet the rewritten behaviour often depends on them. A migration team that declares the code complete while Basis reconstructs these dependencies during cutover has not completed the code assessment.

Compilation proves less than people want it to

A clean syntax check proves that the compiler accepts the program against the new environment. It does not prove that the program reads the same records, applies the same ordering, posts the same documents, respects the same locks or finishes inside its batch window. Compatibility is a necessary gate and a weak business test.

S/4HANA changes data models and exposes compatibility views in places to ease transition. That can keep old reads alive while hiding an architectural problem. Code that reads a compatibility view may return plausible data, yet bypass the released API or semantic model the new design expects. The correct decision may be to replace the access, retire the custom path or keep it temporarily with an explicit expiry. A green ATC result cannot make that design choice.

Implicit database behaviour is another source of false confidence. Consider an old routine like this:

SELECT * FROM vbap
  INTO TABLE @DATA(items)
  WHERE vbeln = @order_number.

READ TABLE items INDEX 1 INTO DATA(first_item).

Without an ORDER BY, the database does not promise which row appears first. If later code treats index one as the earliest line, a database or execution-plan change can alter the outcome without any syntax error. The repair is not to add arbitrary sorting until a test passes. The team must recover the intended business rule, encode it explicitly and test boundary cases such as rejected, renumbered or deleted items.

Native SQL, database hints, pooled or cluster table assumptions, direct updates to SAP-owned tables and broad SELECT * patterns deserve attention, but they are not the whole assessment. Dynamic calls, field-symbol-heavy routines and generated statements can defeat simple static tracing. Pair automated findings with focused reading around high-consequence entry points. Static analysis gives you a map; it does not tell you why the road was built.

User exits and BAdIs are contracts, not containers

An enhancement implementation cannot be judged only by the code inside it. Its real contract includes when SAP calls it, which data is complete at that moment, whether updates occur in dialog or update tasks, which exceptions the caller handles and what later standard logic may overwrite. A replacement BAdI with a similar name may have a different contract.

Classic user exits and customer exits often carry compact code with disproportionate business weight: a few lines can derive a profit centre, reject an order, change pricing or route an approval. During assessment, record the trigger, input state, side effects, error behaviour and downstream consumer for each implementation. Then map it to the target extension point recommended for the exact S/4HANA release and deployment model. Do not assume an on-premise enhancement option exists in the same form in every target.

The popular recommendation to replace every exit with a BAdI immediately is too crude. It sounds modern and gives the programme an easy metric, but the container does not determine the design quality. Some logic belongs in a released in-app extension, some in a side-by-side service, some in standard configuration and some should disappear. Moving opaque logic into a newer hook preserves the opacity.

Modifications to SAP objects need an even harder decision. Ask why the modification existed, whether SAP later supplied the capability, and whether the business still relies on the difference. SPAU work should not become a ritual of reapplying every historical change. Each reapplied modification increases the future upgrade burden, so its owner should defend it with current evidence and a test that fails when it is absent.

Document the decision as a contract: given this business event and state, the extension must produce these changes or this error, and must not change these protected fields. That statement becomes useful whether the target is ABAP, configuration, Go or a workflow outside the core.

Usage data needs a business calendar

Prove ECC behaviour survives
Recorded production traffic drives a parity harness that compares rewritten behaviour with the original.

Runtime evidence is essential, but an observation window is not representative merely because it is long. SAP estates contain quarter close, year-end tax, annual inventory, seasonal pricing, audit extracts and jobs triggered only during exceptional operations. An unused-code decision needs a business calendar and an owner, not just a last-executed timestamp.

Use SCMON to collect procedure-level usage and SUSG to aggregate the results for custom-code analysis. Combine that evidence with workload history, batch schedules and interface monitoring. The observation period should deliberately include the events that matter to the organisation. If it cannot include an annual event, inspect the prior run evidence and interview the operator who reconciles its output.

Classify candidates as keep, change, retire or unresolved. Do not delete unresolved code to improve a dashboard. Retirement requires three pieces of evidence: no relevant execution, no configuration or indirect entry path, and a business owner who accepts removal. Archive the decision and dependency evidence so a late objection can be resolved without restarting discovery.

Usage also helps select tests. High-frequency code gives plenty of production traffic, but low-frequency and high-consequence paths need curated fixtures. A rarely used credit release or tax correction may deserve deeper testing than a report opened every morning. Rank by the damage caused by a wrong result, the difficulty of detection and the availability of recovery.

One more trap is duplicated logic. Two Z-programs may calculate the same concept differently for dialog and batch. Runtime analysis sees two active objects; business analysis should see one disputed rule. Surface those disagreements before migration. Rewriting both faithfully would preserve a defect in organisational knowledge.

Simplification findings need decisions, not closure codes

SAP Readiness Check, the Simplification Item Catalog and ATC checks provide essential evidence, but each finding still needs interpretation in the local design. A simplification item tells you that a technical or functional change matters. It does not know whether your custom program is obsolete, whether a compatibility path is acceptable for a transition, or which business result must survive.

For each finding, record the impacted object, the affected process, the proposed disposition, the target mechanism, the test that proves the decision and the person who accepts it. Avoid closure notes such as "adjusted" or "not relevant" without evidence. Six months later, nobody can tell whether "not relevant" meant unreachable code, a false positive, a retired process or an assumption that was never checked.

A practical review sequence looks like this:

  1. Run target-release ATC checks over the complete custom scope, including modifications and namespaces.
  2. Join findings to observed usage and dependency clusters rather than reviewing objects alphabetically.
  3. Trace each high-consequence cluster to a business entry point and an accountable owner.
  4. Choose retire, retain temporarily, adapt or redesign, with the reason written down.
  5. Attach executable evidence: a regression case, reconciled output, recorded interface exchange or approved exception.

This sequence prevents a common failure where developers clear thousands of local findings while the programme misses one cross-system process. Finding counts measure work queue size. They do not measure readiness. A cluster with twelve findings and a known parity test can be safer than one dynamically constructed posting routine that no tool resolves.

Keep exemptions narrow and dated. If a finding remains because a compatibility view is allowed during transition, name the release assumption and the removal condition. Permanent waivers without a design record become the next migration team's archaeology.

Interfaces fail at the edges of ownership

Finish before maintenance ends
Every CodeHero rewrite project is delivered in under 30 days, including the parity evidence.

An interface assessment must cover the protocol, the payload semantics and the operating agreement. Teams often inventory RFCs, IDocs, APIs and files, then mark an interface as understood because they know its endpoint. The failures hide in field meanings, sequencing, duplicate handling, acknowledgements and the manual repair path used when either side is unavailable.

Begin with observed exchanges and configuration, not the interface name in a catalogue. Record who initiates the exchange, its schedule or trigger, authentication method, payload version, expected volume shape, timeout, retry policy, idempotency rule, ordering assumption and reconciliation owner. For file interfaces, include naming rules, character encoding, delimiters, control totals, landing directories and archive behaviour. For IDocs, retain message type, basic type, extensions, partner profiles, status handling and the jobs that reprocess failures. For RFCs, find external callers as well as destinations configured inside SAP.

Custom ABAP often exposes a data contract accidentally. A consumer may depend on a field that the function module never documented, a particular message text, blank versus zero, or the order of rows in an extract. S/4HANA may supply a cleaner released API, but switching endpoints does not make those consumer assumptions disappear. Compare the old and new contracts field by field, then decide whether to adapt the consumer, place a compatibility layer at the boundary or version the exchange.

Reconciliation deserves its own test. A successful HTTP response or green IDoc status proves delivery through one technical stage. It does not prove that both systems accepted the same business event exactly once. Define the business key used to match records, the totals or states that operators compare, the acceptable delay, and the procedure for replaying a failed item without duplicating a posting. Capture examples of current exceptions because the repair process may contain business rules missing from the program.

I ask teams to walk one failure all the way through. Suppose ECC writes a nightly pricing file, transfers it to a warehouse system and archives the source. The transfer times out after the receiver stores the file but before ECC records success. The retry sends a second copy. If the receiver identifies files only by arrival name, it imports both and inventory valuation changes twice. The migration decision must preserve or improve duplicate detection, not merely reproduce the successful run. A parity fixture should exercise the timeout, replay and reconciliation path.

Interfaces also constrain cutover sequencing. If an external system cannot accept the new contract on the same date, define a bounded coexistence path and the owner who will remove it. Avoid bidirectional compatibility layers with unclear state ownership. They look flexible in a plan and become permanent when nobody can prove which side holds the authoritative record.

Treat every undocumented consumer as an open risk. Search network and gateway records where available, inspect technical-user activity, review file pickup logs and ask operators which extracts they move by hand. Then make the contract explicit before changing the producer. The worst time to discover a small desktop database still consumes a Z-report is after the first close on the new system.

Parity must be recorded before the rewrite

The best time to capture expected behaviour is while the ECC system still processes real work and the finance, supply-chain and operations teams still reconcile it. A rewrite tested only against hand-built examples will miss the odd combinations accumulated through years of actual use.

Build a parity harness around business boundaries. For reports, compare sorted result sets and totals, with documented tolerances for fields whose representation legitimately changes. For interfaces, record requests, responses, IDocs, files and side effects, then replay sanitised cases against the target. For postings, compare document types, account assignments, amounts, currencies, tax treatment, status transitions and error messages that external operators depend on. Mask sensitive data without destroying the combinations that drive logic.

A useful fixture record can be simple:

{
  "case_id": "sales-order-credit-hold",
  "entry_point": "order_create",
  "input_ref": "fixture/credit-hold-017.json",
  "expected": {
    "status": "HELD",
    "posted_documents": 0,
    "message_id": "ZCREDIT-014"
  }
}

The identifiers are illustrative, but the shape forces a team to state what counts as equal. Add preconditions and protected side effects where necessary. Store both the raw captured result and the normalized comparison so reviewers can see what the harness ignored. If the normalization removes timestamps, ordering or generated identifiers, document why those differences have no business meaning.

Recorded production traffic needs careful selection. Replaying every call is rarely necessary, and raw volume can overrepresent easy happy paths. Select equivalence classes, boundary amounts, uncommon status combinations, error paths and each known regulatory or contractual branch. Then add cases for rules discovered during code reading even if they did not appear in the capture window.

Parity is not a demand to preserve poor architecture. It fixes the externally meaningful behaviour while allowing the target to use cleaner boundaries and data ownership. CodeHero uses this approach when rewriting ABAP: its platform reads the whole tree, and a parity harness checks the new system against recorded production traffic while the architecture changes. The harness, not resemblance between old and new source files, supports the acceptance decision.

Some ABAP should not move into S/4HANA

Handle the million-line estate
The platform processes systems over a million lines without splitting the assessment into isolated fragments.

A migration is an opportunity to reduce the custom core, but "clean core" is not a command to move every questionable program to another platform. Location follows the behaviour, transaction boundary, data ownership, latency and support model. Moving a tightly coupled validation into a remote service can add failure modes without creating a useful boundary.

Keep logic near the core when it must participate synchronously in an SAP transaction and the target offers a released extension mechanism with the required contract. Move logic out when it owns a distinct capability, can work through released APIs or events, and benefits from an independent lifecycle. Replace custom code with standard S/4HANA behaviour when the business accepts the standard rule. Retire code when evidence shows the process no longer exists.

The target language is a secondary decision. Go can suit services with clear interfaces and operational ownership. Rust can suit numeric kernels where correctness and control matter. TypeScript can suit user-facing clients and workflow surfaces. None of those choices repairs a missing business contract. If a team cannot say what an ABAP routine must do, translating it into a fashionable language only makes the uncertainty more expensive.

Beware of remote code that still treats SAP tables as its private database. Extracting a Z-program while preserving direct table coupling creates a distributed monolith with network failures added. Define an API or event contract, decide which system owns state, specify retry and idempotency behaviour, and test partial failure. A clean diagram that omits reconciliation is not a finished design.

There is also a people boundary. ABAP specialists often understand the exceptions that architecture teams dismiss as technical debt. Pair them with process owners and target engineers. The goal is not to preserve every old implementation, but to avoid discarding knowledge embedded in it before the business rule has another home.

The assessment deliverable must support a go or no-go decision

A credible assessment lets an executive see what can be retired, what can be adapted, what must be redesigned, what remains unknown and which evidence supports each claim. It also lets an engineer trace a headline risk back to objects, dependencies, traffic and tests. If either audience needs a separate oral history to understand the result, the deliverable is incomplete.

Organise the work by business capability and dependency cluster, not by thousands of repository objects. For each cluster, show scope, current entry points, usage evidence, simplification impacts, data and interface dependencies, target disposition, parity coverage, owner and unresolved decisions. Estimate and sequence at cluster level because objects inside a posting or fulfilment path rarely migrate independently.

Set explicit exit criteria for assessment. Every in-scope custom object should belong to a cluster or a justified retirement set. Every high-consequence cluster needs a target disposition and owner. Every retained behaviour needs an identified test source. Every unresolved item needs a decision date and the evidence required to close it. These criteria expose uncertainty instead of hiding it inside a percentage-complete report.

Do not let the programme call discovery complete while production evidence remains uncaptured. Record representative traffic, reconciled outputs and exceptional runs now, while ECC is available and trusted. Static checks can be rerun later. A missed year-end branch or undocumented external caller may not be recoverable on demand.

The 2027 deadline is real because maintenance choices become narrower and more expensive, but panic is a poor planning method. The immediate action is precise: authorize runtime collection, freeze an inventory format, identify the first high-consequence business cluster and capture its behaviour. Once that evidence exists, target architecture, cost and schedule arguments become engineering decisions instead of guesses.

Budget the assessment for uncertainty, not only known remediation. Set aside explicit decision capacity for objects with no owner, dynamically constructed calls, unreproducible reports and interfaces whose consumers cannot yet be identified. Those are not administrative loose ends. They are the places where scope changes late because somebody finally discovers what the code does.

Keep the evidence under version control and update it as the programme changes ECC. A new emergency transport, a revised job variant or an interface change after initial capture can invalidate a dependency map and its tests. Establish a small intake rule: every production change during the migration window must state which cluster, disposition and parity fixtures it affects. That rule prevents the baseline from quietly drifting away from the system you will actually convert.

Finally, rehearse the decision process as well as the software. Give owners a real ambiguous cluster and require them to choose a target, approve retired behaviour and accept the parity evidence. If nobody has authority to make that call during assessment, the same issue will wait in a cutover meeting with less time and worse options.

FAQ

Will Z-programs run unchanged on S/4HANA?

Some will compile and run, but that does not prove their results remain correct. Check changed data models, removed transactions, extension contracts, database assumptions and the business behaviour around every active dependency cluster.

What is the SAP ECC maintenance deadline?

SAP has committed mainstream maintenance for the core SAP Business Suite 7 applications through the end of 2027, with optional extended maintenance through the end of 2030. Treat 2027 as the delivery boundary unless your organisation has deliberately purchased and planned around the extension.

Which tools find custom ABAP affected by S/4HANA?

Use SAP Readiness Check, target-release ATC checks and the Simplification Item Catalog for impact evidence. Add SCMON, SUSG, ST03N, SM37, interface records and dependency analysis because static tools cannot tell you which business behaviour still matters.

Can unused ABAP code be deleted before migration?

Yes, after you establish that it has no relevant execution, indirect trigger or configured entry path and a business owner accepts retirement. Observation must cover the business calendar, including annual and exceptional processing.

Do user exits have direct replacements in S/4HANA?

Not always. Map the trigger, available data, side effects and error contract to the target release, then decide whether the behaviour belongs in a released BAdI, configuration, an external service or nowhere.

Does a clean ATC result mean custom code is ready?

No. ATC detects defined technical patterns, while readiness also depends on runtime use, process ownership, interface behaviour, performance and parity of business results.

Should all custom ABAP move outside the SAP core?

No. Logic that must participate synchronously in an SAP transaction may belong in a released in-core extension. Externalise a capability when it has a clean contract, clear data ownership and a supportable failure model.

How do you test an ABAP rewrite against ECC?

Capture representative inputs and reconciled outputs at business boundaries, replay them against the target and compare normalized results. Include error paths, boundary values, rare status combinations and protected side effects, not just frequent happy paths.

How early should an S/4HANA custom-code assessment start?

Start while ECC still carries normal production traffic and before the target scope hardens. You need enough time to observe calendar-dependent jobs, resolve ownership and redesign clusters whose behaviour cannot move unchanged.

What should a custom-code assessment deliver?

It should deliver a joined inventory, dependency clusters, usage and simplification evidence, target dispositions, parity-test sources, accountable owners and explicit unknowns. Object counts alone cannot support a go or no-go decision.