diff --git a/ion/src/main/java/com/fasterxml/jackson/dataformat/ion/IonParser.java b/ion/src/main/java/com/fasterxml/jackson/dataformat/ion/IonParser.java
index 706068237..1948b9fe3 100644
--- a/ion/src/main/java/com/fasterxml/jackson/dataformat/ion/IonParser.java
+++ b/ion/src/main/java/com/fasterxml/jackson/dataformat/ion/IonParser.java
@@ -53,6 +53,18 @@ public enum Feature implements FormatFeature // in 2.12
          * @since 2.12.3
          */
         USE_NATIVE_TYPE_ID(true),
+        /**
+         * Whether to convert "null" to an IonValueNull (true);
+         * or leave as a java null (false) when deserializing.
+         *
+         * Enabled by default for backwards compatibility as that has been the behavior
+         * of `jackson-dataformat-ion` since 2.13.
+         *
+         * @see The Ion Specification
+         *
+         * @since 2.19.0
+         */
+        READ_NULL_AS_IONVALUE(true),
         ;
 
         final boolean _defaultState;
@@ -563,6 +575,17 @@ private IonValue getIonValue() throws IOException {
         writer.writeValue(_reader);
         IonValue v = l.get(0);
         v.removeFromContainer();
+
+        if (!Feature.READ_NULL_AS_IONVALUE.enabledIn(_formatFeatures)) {
+            // 2025-04-11, seadbrane: The default is to read 'null' as an Ion Null object.
+            // However, there is no way to determine from the serialized ion data if a 'null'
+            // was an IonNullValue or a 'null' container type such as IonNullStruct or IonNullList.
+            // So if READ_NULL_AS_IONVALUE is disabled, then return 'null' if the _valueToken
+            // is 'null' and the Ion value read is not container type already.
+            if (v.isNullValue() && _valueToken == JsonToken.VALUE_NULL && !IonType.isContainer(v.getType())) {
+                return null;
+            }
+        }
         return v;
     }
 
diff --git a/ion/src/main/java/com/fasterxml/jackson/dataformat/ion/ionvalue/IonValueDeserializer.java b/ion/src/main/java/com/fasterxml/jackson/dataformat/ion/ionvalue/IonValueDeserializer.java
index 0835a989b..bd04adf7c 100644
--- a/ion/src/main/java/com/fasterxml/jackson/dataformat/ion/ionvalue/IonValueDeserializer.java
+++ b/ion/src/main/java/com/fasterxml/jackson/dataformat/ion/ionvalue/IonValueDeserializer.java
@@ -16,21 +16,40 @@
 
 import java.io.IOException;
 
-import com.amazon.ion.*;
-
 import com.fasterxml.jackson.core.JsonParser;
 import com.fasterxml.jackson.core.JsonToken;
 import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
 import com.fasterxml.jackson.databind.util.AccessPattern;
 import com.fasterxml.jackson.dataformat.ion.IonParser;
+import com.amazon.ion.*;
 
 /**
  * Deserializer that knows how to deserialize an IonValue.
  */
-class IonValueDeserializer extends JsonDeserializer {
+class IonValueDeserializer extends JsonDeserializer implements ContextualDeserializer {
+
+    private final JavaType _targetType;
+
+    public IonValueDeserializer() {
+        this._targetType = null;
+    }
+
+    public IonValueDeserializer(JavaType targetType) {
+        this._targetType = targetType;
+    }
+
+    @Override
+    public JsonDeserializer> createContextual(DeserializationContext ctxt, BeanProperty property) {
+        JavaType contextualType = (property != null)
+            ? property.getType()
+            : ctxt.getContextualType(); // fallback
+        return new IonValueDeserializer(contextualType);
+    }
 
     @Override
     public IonValue deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
+
         Object embeddedObject = jp.getEmbeddedObject();
         if (embeddedObject instanceof IonValue) {
             return (IonValue) embeddedObject;
@@ -62,17 +81,34 @@ public IonValue getNullValue(DeserializationContext ctxt) throws JsonMappingExce
                 if (embeddedObj instanceof IonValue) {
                     IonValue iv = (IonValue) embeddedObj;
                     if (iv.isNullValue()) {
+                        if (IonType.isContainer(iv.getType())) {
+                            return iv;
+                        }
+                        IonType containerType = getIonContainerType();
+                        if (containerType != null) {
+                            IonSystem ionSystem = ((IonParser) parser).getIonSystem();
+                            return ionSystem.newNull(containerType);
+                        }
                         return iv;
                     }
                 }
             }
-
             return super.getNullValue(ctxt);
         } catch (IOException e) {
             throw JsonMappingException.from(ctxt, e.toString());
         }
     }
 
+    private IonType getIonContainerType() {
+        if (_targetType != null) {
+            Class> clazz = _targetType.getRawClass();
+            if (IonStruct.class.isAssignableFrom(clazz)) return IonType.STRUCT;
+            if (IonList.class.isAssignableFrom(clazz)) return IonType.LIST;
+            if (IonSexp.class.isAssignableFrom(clazz)) return IonType.SEXP;
+        }
+        return null;
+    }
+
     @Override
     public AccessPattern getNullAccessPattern() {
         return AccessPattern.DYNAMIC;
diff --git a/ion/src/test/java/com/fasterxml/jackson/dataformat/ion/ionvalue/IonValueDeserializerTest.java b/ion/src/test/java/com/fasterxml/jackson/dataformat/ion/ionvalue/IonValueDeserializerTest.java
index 7c97012e6..430cba2fa 100644
--- a/ion/src/test/java/com/fasterxml/jackson/dataformat/ion/ionvalue/IonValueDeserializerTest.java
+++ b/ion/src/test/java/com/fasterxml/jackson/dataformat/ion/ionvalue/IonValueDeserializerTest.java
@@ -1,17 +1,25 @@
 package com.fasterxml.jackson.dataformat.ion.ionvalue;
 
-import java.io.IOException;
-import java.util.*;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+import com.amazon.ion.IonSystem;
+import com.amazon.ion.IonValue;
+import com.amazon.ion.IonStruct;
 
-import com.amazon.ion.*;
-import com.amazon.ion.system.IonSystemBuilder;
 import org.junit.jupiter.api.Test;
 
-import com.fasterxml.jackson.annotation.*;
+import com.amazon.ion.system.IonSystemBuilder;
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.PropertyNamingStrategies;
 import com.fasterxml.jackson.databind.util.AccessPattern;
 import com.fasterxml.jackson.dataformat.ion.IonObjectMapper;
+import com.fasterxml.jackson.dataformat.ion.IonParser;
 
-import static com.fasterxml.jackson.databind.PropertyNamingStrategies.SNAKE_CASE;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNull;
 
@@ -65,7 +73,10 @@ static class IonValueData extends Data {
     }
 
     private static final IonSystem SYSTEM = IonSystemBuilder.standard().build();
-    private static final IonValueMapper ION_VALUE_MAPPER = new IonValueMapper(SYSTEM, SNAKE_CASE);
+    private static final IonValueMapper ION_VALUE_MAPPER
+        = new IonValueMapper(SYSTEM, PropertyNamingStrategies.SNAKE_CASE);
+    private static final IonValueMapper ION_MAPPER_READ_NULL_DISABLED
+        = (IonValueMapper) new IonValueMapper(SYSTEM, PropertyNamingStrategies.SNAKE_CASE).disable(IonParser.Feature.READ_NULL_AS_IONVALUE);
 
     @Test
     public void shouldBeAbleToDeserialize() throws Exception {
@@ -91,24 +102,48 @@ public void shouldBeAbleToDeserializeIncludingNullList() throws Exception {
         assertEquals(ion("null.list"), data.getAllData().get("c"));
     }
 
+    @Test
+    public void shouldBeAbleToDeserializeNullToIonNull() throws Exception {
+        verifyNullDeserialization("{c:null}", SYSTEM.newNull(), null);
+    }
+
     @Test
     public void shouldBeAbleToDeserializeNullList() throws Exception {
-        IonValue ion = ion("{c:null.list}");
+        verifyNullDeserialization("{c:null.list}", SYSTEM.newNullList());
+    }
 
-        IonValueData data = ION_VALUE_MAPPER.readValue(ion, IonValueData.class);
 
-        assertEquals(1, data.getAllData().size());
-        assertEquals(SYSTEM.newNullList(), data.getAllData().get("c"));
-    }
 
     @Test
     public void shouldBeAbleToDeserializeNullStruct() throws Exception {
-        IonValue ion = ion("{c:null.struct}");
+        verifyNullDeserialization("{c:null.struct}", SYSTEM.newNullStruct());
+    }
 
-        IonValueData data = ION_VALUE_MAPPER.readValue(ion, IonValueData.class);
+    @Test
+    public void shouldBeAbleToDeserializeNullSexp() throws Exception {
+        verifyNullDeserialization("{c:null.sexp}", SYSTEM.newNullSexp());
+    }
+
+    private void verifyNullDeserialization(String ionString, IonValue expected) throws Exception {
+         verifyNullDeserialization(ionString, expected, expected);
+    }
+
+    private void verifyNullDeserialization(String ionString, IonValue expected, IonValue expectedReadNullDisabled) throws Exception {
+        verifyNullDeserialization(ION_VALUE_MAPPER, ionString, expected);
+        verifyNullDeserialization(ION_MAPPER_READ_NULL_DISABLED, ionString, expectedReadNullDisabled);
+    }
+
+    private void verifyNullDeserialization(IonValueMapper mapper, String ionString, IonValue expected) throws Exception {
+        IonValueData data = mapper.readValue(ionString, IonValueData.class);
+
+        assertEquals(1, data.getAllData().size());
+        assertEquals(expected, data.getAllData().get("c"));
+
+        IonValue ion = ion(ionString);
+        data = mapper.readValue(ion, IonValueData.class);
 
         assertEquals(1, data.getAllData().size());
-        assertEquals(SYSTEM.newNullStruct(), data.getAllData().get("c"));
+        assertEquals(expected, data.getAllData().get("c"));
     }
 
     @Test
@@ -154,6 +189,22 @@ public void shouldBeAbleToSerializeAndDeserializePojo() throws Exception {
         assertEquals(source, result);
     }
 
+    @Test
+    public void shouldBeAbleToSerializeAndDeserializeIonValueDataWithIncludeNonNull() throws Exception {
+        IonValueData source = new IonValueData();
+        source.put("a", SYSTEM.newInt(1));
+        source.put("b", SYSTEM.newNull());
+        source.put("c", null);
+        IonValueMapper mapper = (IonValueMapper) ION_VALUE_MAPPER.copy().setSerializationInclusion(JsonInclude.Include.NON_NULL);
+
+        String data = mapper.writeValueAsString(source);
+        assertEquals("{a:1,b:null}", data);
+        // Now remove the null element for the comparison below.
+        source.getAllData().remove("c");
+        IonValueData result = mapper.readValue(data, IonValueData.class);
+        assertEquals(source, result);
+    }
+
     @Test
     public void shouldBeAbleToSerializeAndDeserializeStringData() throws Exception {
         StringData source = new StringData();
@@ -162,7 +213,17 @@ public void shouldBeAbleToSerializeAndDeserializeStringData() throws Exception {
 
         IonValue data = ION_VALUE_MAPPER.writeValueAsIonValue(source);
         StringData result = ION_VALUE_MAPPER.parse(data, StringData.class);
+        assertEquals(source, result);
+    }
+
+    @Test
+    public void shouldBeAbleToSerializeAndDeserializeStringDataAsString() throws Exception {
+        StringData source = new StringData();
+        source.put("a", "1");
+        source.put("b", null);
 
+        String data = ION_VALUE_MAPPER.writeValueAsString(source);
+        StringData result = ION_VALUE_MAPPER.readValue(data, StringData.class);
         assertEquals(source, result);
     }
 
@@ -180,7 +241,7 @@ static class MyBean {
     }
 
     @Test
-    public void testWithMissingProperty() throws IOException
+    public void testWithMissingProperty() throws Exception
     {
         IonSystem ionSystem = IonSystemBuilder.standard().build();
         IonObjectMapper ionObjectMapper = IonObjectMapper.builder(ionSystem)
diff --git a/release-notes/CREDITS-2.x b/release-notes/CREDITS-2.x
index 6348ee0a8..8dec9da09 100644
--- a/release-notes/CREDITS-2.x
+++ b/release-notes/CREDITS-2.x
@@ -381,3 +381,7 @@ Cormac Redmond (@credmond)
 Manuel Sugawara (@sugmanue)
  * Contributed #568: Improve ASCII decoding performance for `CBORParser`
   (2.19.0)
+
+Josh Curry (@seadbrane)
+ * Reported, contributed fix for #571: Unable to deserialize a pojo with IonStruct
+  (2.19.0)
diff --git a/release-notes/VERSION-2.x b/release-notes/VERSION-2.x
index 135d01caa..213be7c18 100644
--- a/release-notes/VERSION-2.x
+++ b/release-notes/VERSION-2.x
@@ -14,6 +14,9 @@ Active maintainers:
 === Releases ===
 ------------------------------------------------------------------------
 
+#571: Unable to deserialize a pojo with IonStruct
+ (reported, fix contributed by Josh C)
+
 2.19.0-rc2 (07-Apr-2025)
 
 #300: (smile) Floats are encoded with sign extension while doubles without