diff --git a/src/Context/FieldResolver.php b/src/Context/FieldResolver.php
index d3bb6a1..99883e6 100644
--- a/src/Context/FieldResolver.php
+++ b/src/Context/FieldResolver.php
@@ -4,6 +4,7 @@ namespace Drupal\jsonapi\Context;
 
 use Drupal\Core\Entity\EntityFieldManagerInterface;
 use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
+use Drupal\Core\Entity\FieldableEntityInterface;
 use Drupal\Core\Field\TypedData\FieldItemDataDefinition;
 use Drupal\Core\TypedData\DataReferenceTargetDefinition;
 use Drupal\jsonapi\ResourceType\ResourceType;
@@ -133,6 +134,13 @@ class FieldResolver {
     while ($part = array_shift($parts)) {
       $field_name = $this->getInternalName($part, $resource_types);
 
+      // If none of the resource types are traversable, assume that the
+      // remaining path parts are for sub-properties.
+      if (!$this->resourceTypesAreTraversable($resource_types)) {
+        $reference_breadcrumbs[] = $field_name;
+        return $this->constructInternalPath($reference_breadcrumbs, $parts);
+      }
+
       $candidate_definitions = $this->getFieldItemDefinitions(
         $resource_types,
         $field_name
@@ -156,21 +164,36 @@ class FieldResolver {
       // $field_name may not be a reference field. In that case we should treat
       // the rest of the parts as sub-properties of the field.
       if (empty($resource_types)) {
-        // Reconstruct the path parts that are referencing sub-properties.
-        $field_path = implode('.', $parts);
-
-        // This rebuilds the path from the real, internal field names that have
-        // been traversed so far. It joins them with the "entity" keyword as
-        // required by the entity query system.
-        $entity_path = implode('.entity.', $reference_breadcrumbs);
-
-        // Reconstruct the full path to the final reference field.
-        return (empty($field_path)) ? $entity_path : $entity_path . '.' . $field_path;
+        return $this->constructInternalPath($reference_breadcrumbs, $parts);
       }
     }
 
     // Reconstruct the full path to the final reference field.
-    return implode('.entity.', $reference_breadcrumbs);
+    return $this->constructInternalPath($reference_breadcrumbs);
+  }
+
+  /**
+   * Expand the internal path with the "entity" keyword.
+   *
+   * @param string[] $references
+   *   The resolved internal field names of all entity references.
+   * @param string[] $property_path
+   *   (optional) A sub-property path for the last field in the path.
+   *
+   * @return string
+   *   The expanded and imploded path.
+   */
+  protected function constructInternalPath(array $references, array $property_path = []) {
+    // Reconstruct the path parts that are referencing sub-properties.
+    $field_path = implode('.', $property_path);
+
+    // This rebuilds the path from the real, internal field names that have
+    // been traversed so far. It joins them with the "entity" keyword as
+    // required by the entity query system.
+    $entity_path = implode('.entity.', $references);
+
+    // Reconstruct the full path to the final reference field.
+    return (empty($field_path)) ? $entity_path : $entity_path . '.' . $field_path;
   }
 
   /**
@@ -186,7 +209,10 @@ class FieldResolver {
    */
   protected function getFieldItemDefinitions(array $resource_types, $field_name) {
     return array_reduce($resource_types, function ($result, $resource_type) use ($field_name) {
-      /* @var \Drupal\jsonapi\ResourceType\ResourceType $resource_type */
+      /** @var \Drupal\jsonapi\ResourceType\ResourceType $resource_type */
+      if (!$resource_type->isTraversable()) {
+        return $result;
+      }
       $entity_type = $resource_type->getEntityTypeId();
       $bundle = $resource_type->getBundle();
       $definitions = $this->fieldManager->getFieldDefinitions($entity_type, $bundle);
@@ -238,6 +264,24 @@ class FieldResolver {
     }, []);
   }
 
+  /**
+   * Whether the given resources can be traversed to other resources.
+   *
+   * @param \Drupal\jsonapi\ResourceType\ResourceType[] $resource_types
+   *   The resources types to evaluate.
+   *
+   * @return bool
+   *   TRUE if any one of the given resource types is traversable.
+   */
+  protected function resourceTypesAreTraversable(array $resource_types) {
+    foreach ($resource_types as $resource_type) {
+      if ($resource_type->isTraversable()) {
+        return TRUE;
+      }
+    }
+    return FALSE;
+  }
+
   /**
    * Build a list of resource types depending on which bundles are referenced.
    *
diff --git a/src/ResourceType/ResourceType.php b/src/ResourceType/ResourceType.php
index 1ef2133..d2c9cf3 100644
--- a/src/ResourceType/ResourceType.php
+++ b/src/ResourceType/ResourceType.php
@@ -28,6 +28,13 @@ class ResourceType {
    */
   protected $bundle;
 
+  /**
+   * Whether this resource type can have relationships.
+   *
+   * @var bool
+   */
+  protected $traversable;
+
   /**
    * The type name.
    *
@@ -77,6 +84,21 @@ class ResourceType {
     return $this->bundle;
   }
 
+  /**
+   * Whether this resource type is traversable.
+   *
+   * Some resource types may not support filtering, sorting, or inclusions of
+   * related resources. For example, config entities, which are stored in YAML,
+   * cannot be filtered by related resources because a SQL join can't be
+   * constructed.
+   *
+   * @return bool
+   *   TRUE if resources of this type can have relationships.
+   */
+  public function isTraversable() {
+    return $this->traversable;
+  }
+
   /**
    * Gets the deserialization target class.
    *
@@ -151,12 +173,15 @@ class ResourceType {
    *   An entity type ID.
    * @param string $bundle
    *   A bundle.
+   * @param bool $traversable
+   *   Whether resources of this type can have relationships.
    * @param string $deserialization_target_class
    *   The deserialization target class.
    */
-  public function __construct($entity_type_id, $bundle, $deserialization_target_class) {
+  public function __construct($entity_type_id, $bundle, $traversable, $deserialization_target_class) {
     $this->entityTypeId = $entity_type_id;
     $this->bundle = $bundle;
+    $this->traversable = $traversable;
     $this->deserializationTargetClass = $deserialization_target_class;
 
     $this->typeName = sprintf('%s--%s', $this->entityTypeId, $this->bundle);
diff --git a/src/ResourceType/ResourceTypeRepository.php b/src/ResourceType/ResourceTypeRepository.php
index eb8a763..25eff1e 100644
--- a/src/ResourceType/ResourceTypeRepository.php
+++ b/src/ResourceType/ResourceTypeRepository.php
@@ -4,6 +4,7 @@ namespace Drupal\jsonapi\ResourceType;
 
 use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Entity\FieldableEntityInterface;
 use Symfony\Component\HttpKernel\Exception\PreconditionFailedHttpException;
 
 /**
@@ -63,13 +64,15 @@ class ResourceTypeRepository implements ResourceTypeRepositoryInterface {
    */
   public function all() {
     if (!$this->all) {
-      $entity_type_ids = array_keys($this->entityTypeManager->getDefinitions());
-      foreach ($entity_type_ids as $entity_type_id) {
-        $this->all = array_merge($this->all, array_map(function ($bundle) use ($entity_type_id) {
+      /** @var \Drupal\Core\Entity\EntityTypeInterface[] $definitions */
+      $definitions = $this->entityTypeManager->getDefinitions();
+      foreach (array_keys($definitions) as $entity_type_id) {
+        $this->all = array_merge($this->all, array_map(function ($bundle) use ($entity_type_id, $definitions) {
           return new ResourceType(
             $entity_type_id,
             $bundle,
-            $this->entityTypeManager->getDefinition($entity_type_id)->getClass()
+            $definitions[$entity_type_id]->entityClassImplements(FieldableEntityInterface::class),
+            $definitions[$entity_type_id]->getClass()
           );
         }, array_keys($this->bundleManager->getBundleInfo($entity_type_id))));
       }
diff --git a/tests/src/Kernel/Context/FieldResolverTest.php b/tests/src/Kernel/Context/FieldResolverTest.php
index 88e34ae..f6b4601 100644
--- a/tests/src/Kernel/Context/FieldResolverTest.php
+++ b/tests/src/Kernel/Context/FieldResolverTest.php
@@ -68,6 +68,11 @@ class FieldResolverTest extends JsonapiKernelTestBase {
    */
   public function resolveInternalProvider() {
     return [
+      // Config entities
+      ['uuid', 'uuid', 'entity_test_bundle', 'entity_test_bundle'],
+      ['type.entity.uuid', 'type.uuid'],
+
+      // Content entities
       ['field_test1', 'field_test1'],
       ['field_test2', 'field_test2'],
 
