{"id":21216,"date":"2026-03-13T21:41:25","date_gmt":"2026-03-13T20:41:25","guid":{"rendered":"https:\/\/trifork.nl\/blog\/?p=21216"},"modified":"2026-03-13T21:41:26","modified_gmt":"2026-03-13T20:41:26","slug":"fault-injection-with-spring","status":"publish","type":"post","link":"https:\/\/trifork.nl\/blog\/fault-injection-with-spring\/","title":{"rendered":"Fake It Till You Make It: Fault Injection with Spring using Headers and Baggage Propagation"},"content":{"rendered":"\n<p>At Trifork, we build custom software that powers the core business of many clients. For <a href=\"https:\/\/nederlandseloterij.nl\" target=\"_blank\" rel=\"noreferrer noopener\">Nederlandse Loterij<\/a> we\u2019re developing an integration platform that handles, among many other use cases, the purchasing of lottery tickets. This involves some fairly complex orchestration logic, where we are coordinating between the lottery system that issues the tickets and the player account management system that handles the payments and, eventually, registration of the winnings.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"517\" height=\"270\" src=\"https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2026\/03\/image-3.png\" alt=\"\" class=\"wp-image-21226\" srcset=\"https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2026\/03\/image-3.png 517w, https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2026\/03\/image-3-300x157.png 300w\" sizes=\"auto, (max-width: 517px) 100vw, 517px\" \/><\/figure>\n\n\n\n<p>As we are in the process of reworking a lot of this functionality, our QA tester is making sure that all possible scenarios are properly handled: not just the happy flow, but also all failure cases where one of the systems involved has issues in the middle of this orchestration flow.\u00a0<\/p>\n\n\n\n<p>To give you an idea of what this flow looks like: when a player makes a purchase, we first ask the lottery system to verify the purchase and provide the cost. We then make a reservation for that amount in the player\u2019s wallet, and on success ask the lottery system to provision the ticket. We then put a message on a queue to ensure that we complete the reservation with the definitive amount and return the ticket to the player. <br>Asynchronously we\u2019ll complete that reservation, which should eventually be able to succeed as there\u2019s a reservation already.<\/p>\n\n\n\n<p>Many things could fail during this flow: sometimes in a way that leaves us knowing what happened (if we can\u2019t connect to a system at all, or a known specific error is returned, we can be sure that our request wasn\u2019t processed), sometimes in a way where we have no clue (when a system didn\u2019t respond in a timely fashion, or with an unknown internal error).&nbsp;<\/p>\n\n\n\n<p>If the call to provision the ticket fails, we want to make sure that we cancel everything that already happened so far using a <em>compensating transaction<\/em>. If the message handling to finalize the reservation fails, we simply want to keep trying (calls are idempotent) and alert if the retries fail as well, since the player already received their ticket and there is a reservation for it.\u00a0<\/p>\n\n\n\n<p>The problem is: <strong>how do you let a tester simulate all these potential error scenarios?<\/strong> <br>For other cases it\u2019s sometimes as simple as temporarily breaking the connection to a backend system, e.g. by configuring a wrong password or URL. However, for complex flows like the purchasing this doesn\u2019t work: the initial verification call would already fail and nothing would happen.\u00a0<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Fault Injection<\/h2>\n\n\n\n<p>We decided to introduce a mechanism for injecting faults for testing purposes on a <em>per-request basis<\/em>. <br>This can be done by providing a request header with the HTTP request that\u2019s made to our REST API. In the value of this header, you indicate two things: <em>where<\/em> the error should happen and <em>what<\/em> error should be simulated.\u00a0<\/p>\n\n\n\n<p>That header would look something like this:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nX-Force-Fault: LOTTERY_TICKET_CREATE=TIMEOUT_AFTER_SUCCESS\n<\/pre><\/div>\n\n\n<p>This tells the code that handles the creation of a lottery ticket by calling the lottery system to simulate a timeout <em>after<\/em> the ticket was, in fact, successfully provisioned. Other faults that we support are timeouts without result, technical errors or known validation errors.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"500\" height=\"333\" src=\"https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2026\/03\/image-5.png\" alt=\"\" class=\"wp-image-21228\" srcset=\"https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2026\/03\/image-5.png 500w, https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2026\/03\/image-5-300x200.png 300w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/figure>\n\n\n\n<p>Simulating the errors is the easy part: just throw some exception that would also be thrown when the simulated failure scenario would occur. The tricky part is <em>how to check if fault injection has been requested<\/em> in your code.\u00a0<\/p>\n\n\n\n<p>In a single monolithic system without any asynchronous calls, you could of course just check the HTTP request header. In a Spring-MVC web application, you can access the current request (if there is any) by looking it up via the <code>RequestContextHolder<\/code>. <br>However, our platform is a distributed system consisting of many services. That means that when the initial HTTP request is made, it typically calls an internal service to handle the orchestration logic. We want to ensure that the <code>X-Force-Fault<\/code> header is then propagated somehow.<\/p>\n\n\n\n<p>The situation is even trickier when we put a message on a queue to be handled asynchronously: if we want to force a fault in the message handling, we cannot rely on HTTP headers as there is no request then. Also, in this scenario we only want to simulate the fault <em>once<\/em>: subsequent retries should ignore the requested fault, so that we can test if our application properly retries and if the backend system handles retries in an idempotent fashion.<\/p>\n\n\n\n<p>So what can we do?<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Baggage<\/h2>\n\n\n\n<p>I\u2019m a big fan of the <a href=\"https:\/\/www.terrypratchettbooks.com\/book-series\/discworld\/\" target=\"_blank\" rel=\"noreferrer noopener\">Discworld book series<\/a> from the late Terry Pratchett. A recurring \u201ccharacter\u201d in those books is The Luggage: it\u2019s a large magical chest with hundreds of little legs that will move through anything in its way to stay with its owner while keeping their baggage safe.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"1000\" src=\"https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2026\/03\/image.png\" alt=\"\" class=\"wp-image-21218\" style=\"width:562px;height:auto\" srcset=\"https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2026\/03\/image.png 1000w, https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2026\/03\/image-300x300.png 300w, https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2026\/03\/image-150x150.png 150w, https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2026\/03\/image-768x768.png 768w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n\n\n\n<p>As it turns out, <a href=\"https:\/\/docs.micrometer.io\/tracing\/reference\/\" target=\"_blank\" rel=\"noreferrer noopener\">Micrometer Tracing<\/a> (which is the tracing library used by Spring) supports a similar notion called \u201cbaggage\u201d, a concept that I believe originally comes from <a href=\"https:\/\/github.com\/openzipkin\/brave\" target=\"_blank\" rel=\"noreferrer noopener\">Brave<\/a>.\u00a0<\/p>\n\n\n\n<p>Baggage is basically a collection of key-value pairs that can be associated with a trace, and that will magically be propagated along with the trace across its spans.&nbsp;<\/p>\n\n\n\n<p>For HTTP requests, this is done using HTTP request headers. This is however also supported for use cases like sending and receiving SQS messages when using <a href=\"https:\/\/awspring.io\/\" target=\"_blank\" rel=\"noreferrer noopener\">Spring Cloud AWS<\/a> (thanks to the <a href=\"https:\/\/github.com\/awspring\/spring-cloud-aws\/pull\/1369\" target=\"_blank\" rel=\"noreferrer noopener\">excellent work of Tomaz Fernandes<\/a>).\u00a0<\/p>\n\n\n\n<p>So what we can do is configure Spring Boot to propagate our <code>X-Force-Fault<\/code> header by configuring it as a so-called remote baggage field. Here\u2019s what that looks like in a properties file:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nmanagement.tracing.baggage.remote-fields=X-Force-Fault\n<\/pre><\/div>\n\n\n<p>For HTTP requests, this causes the header to both be propagated as-is in calls to backends and also be included as part of a \u201cbaggage\u201d header that combines all fields in a single value based on the <a href=\"https:\/\/www.w3.org\/TR\/baggage\/\" target=\"_blank\" rel=\"noreferrer noopener\">W3C Baggage Propagation specification<\/a>. For SQS messages, only that single <code>baggage<\/code> key-value is added as a message attribute, as SQS only supports 10 attributes per message and the framework shouldn&#8217;t exhaust them when you configure multiple remote fields. <\/p>\n\n\n\n<p>In our code, we now can check for the presence of the baggage field when we need to know if we need to force a fault. <br>Micrometer allows you to do this via its <code>Tracer<\/code> that you can inject as a Spring bean, which provides an abstraction over the actual tracing mechanism that&#8217;s used. Our application is using Brave rather than Open Telemetry for trace propagation, so we can also call the Brave API directly by using its <code>BaggageField<\/code> that uses the current trace context obtained from a <code>ThreadLocal<\/code> variable, which is a little simpler as it doesn&#8217;t require any depency injection:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\npublic class BaggageFetcher {\n   public static String getBaggage(String key) {\n       return BaggageField.getAllValues().entrySet().stream()\n           .filter(kv -&gt; kv.getKey().equalsIgnoreCase(key))\n           .findFirst()\n           .map(kv -&gt; kv.getValue())\n           .orElse(null);\n   }\n}\n<\/pre><\/div>\n\n\n<p>Then we can write a small <code>TesterCaller<\/code> helper to wrap code that needs to force the faults, which I won\u2019t show here.\u00a0<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">One-off faults in message listeners<\/h2>\n\n\n\n<p>As mentioned, for code that handles messages from a queue we want to support fault injection as well, but only for the first delivery attempt: subsequent attempts should ignore the requested fault, as the scenario that we want our tester to be able to simulate is that of a transient error that will be retried successfully. It wouldn&#8217;t make sense to just let every delivery attempt fail in the same way.<\/p>\n\n\n\n<p>The <code>BaggageFetcher<\/code> should work for message handling code just fine, as long as baggage propagation support has been implemented for your messaging oriented middleware of choice.\u00a0As mentioned, Spring Cloud AWS has us covered here: if you&#8217;re using something else, make sure to check if this works for your MoM of choice as well!<\/p>\n\n\n\n<p>That leaves the problem of knowing if we\u2019re inside the first delivery attempt. Using Spring Cloud AWS, this is what I did for SQS:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\n @Bean\n&lt;T&gt; MessageInterceptor&lt;T&gt; receiveCountMessageInterceptor() {\n   return new MessageInterceptor&lt;T&gt;() {\n       @Override\n       public Message&lt;T&gt; intercept(Message&lt;T&gt; message) {\n           var receiveCount = message.getHeaders().get(SQS_APPROXIMATE_RECEIVE_COUNT);\n           if (receiveCount != null) {\n               BaggageField.create(SQS_APPROXIMATE_RECEIVE_COUNT).updateValue(receiveCount.toString());\n           }\n           return message;\n       }\n   };\n}\n<\/pre><\/div>\n\n\n<p>This message interceptor checks the \u201creceive count\u201d for every message that\u2019s received and stores it in another baggage field. There is a difference with our other baggage field, though: this one is really only used as a convenient <code>ThreadLocal<\/code> variable of sorts and doesn\u2019t need to be propagated.\u00a0<br>When you\u2019re using Brave, you can indicate this by configuring a separate property:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nmanagement.tracing.baggage.local-fields=Sqs_Msa_ApproximateReceiveCount\n<\/pre><\/div>\n\n\n<p>Local fields are a Brave-specific feature, but of course you could make this work with Open Telemetry as well by using the <code>Tracer<\/code> API and a remote field. That property&#8217;s value is the value of the <code>io.awspring.cloud.sqs.listener.SqsHeaders.MessageSystemAttributes#SQS_APPROXIMATE_RECEIVE_COUNT<\/code> constant, BTW.<\/p>\n\n\n\n<p>With that, we can now check both if a fault has been requested AND if we\u2019re in the first delivery attempt:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nif (&quot;1&quot;.equals(BaggageField.getAllValues().get(SQS_APPROXIMATE_RECEIVE_COUNT))) {\n   TesterCaller.withRequestedForcedError(() -&gt; lotteryClient.createTicket(req), LOTTERY_TICKET_CREATE);\n} else {\n   lotteryClient.createTicket(req);\n}\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\">Testing our testing code<\/h2>\n\n\n\n<p>On testing this, I initially had some issues: somehow it seemed like the baggage field wasn\u2019t properly propagated when using SQS, although I could see that the message had the expected attribute.<\/p>\n\n\n\n<p>While debugging this, I found that there was a problem in the Micrometer code that parses the baggage field\u2019s contents: it didn\u2019t handle key-value pairs with values containing an equal sign properly. I <a href=\"https:\/\/github.com\/micrometer-metrics\/tracing\/issues\/1350\" target=\"_blank\" rel=\"noreferrer noopener\">reported this<\/a>\u00a0and not only did the team fix this really quickly, they provided point releases containing the fix immediately after that as well! \ud83d\ude4f<\/p>\n\n\n\n<p>With that fix in place, we are now running this on our test environments with several supported injection points and possible faults. Adding additional injection points is trivial, and our tester is very happy that she can finally validate that flows which don\u2019t follow the happy case are behaving correctly as well!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>At Trifork, we build custom software that powers the core business of many clients. For Nederlandse Loterij we\u2019re developing an integration platform that handles, among many other use cases, the purchasing of lottery tickets. This involves some fairly complex orchestration logic, where we are coordinating between the lottery system that issues the tickets and the [&hellip;]<\/p>\n","protected":false},"author":62,"featured_media":21231,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"content-type":"","footnotes":""},"categories":[337,98,94,1],"tags":[564,70,120],"class_list":["post-21216","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-from-the-trenches","category-microservices","category-spring","category-uncategorized","tag-micrometer","tag-spring","tag-testing"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v24.4 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Fake It Till You Make It: Fault Injection with Spring using Headers and Baggage Propagation - Trifork Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/trifork.nl\/blog\/fault-injection-with-spring\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Fake It Till You Make It: Fault Injection with Spring using Headers and Baggage Propagation - Trifork Blog\" \/>\n<meta property=\"og:description\" content=\"At Trifork, we build custom software that powers the core business of many clients. For Nederlandse Loterij we\u2019re developing an integration platform that handles, among many other use cases, the purchasing of lottery tickets. This involves some fairly complex orchestration logic, where we are coordinating between the lottery system that issues the tickets and the [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/trifork.nl\/blog\/fault-injection-with-spring\/\" \/>\n<meta property=\"og:site_name\" content=\"Trifork Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-03-13T20:41:25+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-03-13T20:41:26+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2026\/03\/injection-scaled.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"2560\" \/>\n\t<meta property=\"og:image:height\" content=\"1707\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Joris Kuipers\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Joris Kuipers\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/trifork.nl\/blog\/fault-injection-with-spring\/\",\"url\":\"https:\/\/trifork.nl\/blog\/fault-injection-with-spring\/\",\"name\":\"Fake It Till You Make It: Fault Injection with Spring using Headers and Baggage Propagation - Trifork Blog\",\"isPartOf\":{\"@id\":\"https:\/\/trifork.nl\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/trifork.nl\/blog\/fault-injection-with-spring\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/trifork.nl\/blog\/fault-injection-with-spring\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2026\/03\/injection-scaled.jpg\",\"datePublished\":\"2026-03-13T20:41:25+00:00\",\"dateModified\":\"2026-03-13T20:41:26+00:00\",\"author\":{\"@id\":\"https:\/\/trifork.nl\/blog\/#\/schema\/person\/265bd41e503f7176742258a927de598b\"},\"breadcrumb\":{\"@id\":\"https:\/\/trifork.nl\/blog\/fault-injection-with-spring\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/trifork.nl\/blog\/fault-injection-with-spring\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/trifork.nl\/blog\/fault-injection-with-spring\/#primaryimage\",\"url\":\"https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2026\/03\/injection-scaled.jpg\",\"contentUrl\":\"https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2026\/03\/injection-scaled.jpg\",\"width\":2560,\"height\":1707},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/trifork.nl\/blog\/fault-injection-with-spring\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/trifork.nl\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Fake It Till You Make It: Fault Injection with Spring using Headers and Baggage Propagation\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/trifork.nl\/blog\/#website\",\"url\":\"https:\/\/trifork.nl\/blog\/\",\"name\":\"Trifork Blog\",\"description\":\"Keep updated on the technical solutions Trifork is working on!\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/trifork.nl\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/trifork.nl\/blog\/#\/schema\/person\/265bd41e503f7176742258a927de598b\",\"name\":\"Joris Kuipers\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/trifork.nl\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/9ab8da0d60582bad84342d4602d23dbd?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/9ab8da0d60582bad84342d4602d23dbd?s=96&d=mm&r=g\",\"caption\":\"Joris Kuipers\"},\"sameAs\":[\"http:\/\/www.trifork.nl\"],\"url\":\"https:\/\/trifork.nl\/blog\/author\/jorisk\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Fake It Till You Make It: Fault Injection with Spring using Headers and Baggage Propagation - Trifork Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/trifork.nl\/blog\/fault-injection-with-spring\/","og_locale":"en_US","og_type":"article","og_title":"Fake It Till You Make It: Fault Injection with Spring using Headers and Baggage Propagation - Trifork Blog","og_description":"At Trifork, we build custom software that powers the core business of many clients. For Nederlandse Loterij we\u2019re developing an integration platform that handles, among many other use cases, the purchasing of lottery tickets. This involves some fairly complex orchestration logic, where we are coordinating between the lottery system that issues the tickets and the [&hellip;]","og_url":"https:\/\/trifork.nl\/blog\/fault-injection-with-spring\/","og_site_name":"Trifork Blog","article_published_time":"2026-03-13T20:41:25+00:00","article_modified_time":"2026-03-13T20:41:26+00:00","og_image":[{"width":2560,"height":1707,"url":"https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2026\/03\/injection-scaled.jpg","type":"image\/jpeg"}],"author":"Joris Kuipers","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Joris Kuipers","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/trifork.nl\/blog\/fault-injection-with-spring\/","url":"https:\/\/trifork.nl\/blog\/fault-injection-with-spring\/","name":"Fake It Till You Make It: Fault Injection with Spring using Headers and Baggage Propagation - Trifork Blog","isPartOf":{"@id":"https:\/\/trifork.nl\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/trifork.nl\/blog\/fault-injection-with-spring\/#primaryimage"},"image":{"@id":"https:\/\/trifork.nl\/blog\/fault-injection-with-spring\/#primaryimage"},"thumbnailUrl":"https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2026\/03\/injection-scaled.jpg","datePublished":"2026-03-13T20:41:25+00:00","dateModified":"2026-03-13T20:41:26+00:00","author":{"@id":"https:\/\/trifork.nl\/blog\/#\/schema\/person\/265bd41e503f7176742258a927de598b"},"breadcrumb":{"@id":"https:\/\/trifork.nl\/blog\/fault-injection-with-spring\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/trifork.nl\/blog\/fault-injection-with-spring\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/trifork.nl\/blog\/fault-injection-with-spring\/#primaryimage","url":"https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2026\/03\/injection-scaled.jpg","contentUrl":"https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2026\/03\/injection-scaled.jpg","width":2560,"height":1707},{"@type":"BreadcrumbList","@id":"https:\/\/trifork.nl\/blog\/fault-injection-with-spring\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/trifork.nl\/blog\/"},{"@type":"ListItem","position":2,"name":"Fake It Till You Make It: Fault Injection with Spring using Headers and Baggage Propagation"}]},{"@type":"WebSite","@id":"https:\/\/trifork.nl\/blog\/#website","url":"https:\/\/trifork.nl\/blog\/","name":"Trifork Blog","description":"Keep updated on the technical solutions Trifork is working on!","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/trifork.nl\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/trifork.nl\/blog\/#\/schema\/person\/265bd41e503f7176742258a927de598b","name":"Joris Kuipers","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/trifork.nl\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/9ab8da0d60582bad84342d4602d23dbd?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/9ab8da0d60582bad84342d4602d23dbd?s=96&d=mm&r=g","caption":"Joris Kuipers"},"sameAs":["http:\/\/www.trifork.nl"],"url":"https:\/\/trifork.nl\/blog\/author\/jorisk\/"}]}},"_links":{"self":[{"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/posts\/21216","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/users\/62"}],"replies":[{"embeddable":true,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/comments?post=21216"}],"version-history":[{"count":9,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/posts\/21216\/revisions"}],"predecessor-version":[{"id":21232,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/posts\/21216\/revisions\/21232"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/media\/21231"}],"wp:attachment":[{"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/media?parent=21216"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/categories?post=21216"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/tags?post=21216"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}