diff --git a/src/Microsoft.OpenApi/Models/OpenApiDocument.cs b/src/Microsoft.OpenApi/Models/OpenApiDocument.cs
index 5fee30ac2..f04f47680 100644
--- a/src/Microsoft.OpenApi/Models/OpenApiDocument.cs
+++ b/src/Microsoft.OpenApi/Models/OpenApiDocument.cs
@@ -24,7 +24,7 @@ namespace Microsoft.OpenApi.Models
     public class OpenApiDocument : IOpenApiSerializable, IOpenApiExtensible
     {
         /// 
-        /// Related workspace containing OpenApiDocuments that are referenced in this document
+        /// Related workspace containing components that are referenced in a document
         /// 
         public OpenApiWorkspace Workspace { get; set; }
 
diff --git a/src/Microsoft.OpenApi/Reader/Services/OpenApiWorkspaceLoader.cs b/src/Microsoft.OpenApi/Reader/Services/OpenApiWorkspaceLoader.cs
index 6915d60bd..a3462da70 100644
--- a/src/Microsoft.OpenApi/Reader/Services/OpenApiWorkspaceLoader.cs
+++ b/src/Microsoft.OpenApi/Reader/Services/OpenApiWorkspaceLoader.cs
@@ -28,7 +28,7 @@ internal async Task LoadAsync(OpenApiReference reference,
         {
             _workspace.AddDocumentId(reference.ExternalResource, document.BaseUri);
             var version = diagnostic?.SpecificationVersion ?? OpenApiSpecVersion.OpenApi3_0;
-            _workspace.RegisterComponents(document, version);
+            _workspace.RegisterComponents(document);
             document.Workspace = _workspace;
 
             // Collect remote references by walking document
diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiDocumentDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiDocumentDeserializer.cs
index b0e2a29ae..f33d98465 100644
--- a/src/Microsoft.OpenApi/Reader/V2/OpenApiDocumentDeserializer.cs
+++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiDocumentDeserializer.cs
@@ -252,7 +252,7 @@ public static OpenApiDocument LoadOpenApi(RootNode rootNode)
             FixRequestBodyReferences(openApiDoc);
 
             // Register components
-            openApiDoc.Workspace.RegisterComponents(openApiDoc, OpenApiSpecVersion.OpenApi2_0);
+            openApiDoc.Workspace.RegisterComponents(openApiDoc);
 
             return openApiDoc;
         }
diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiDocumentDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiDocumentDeserializer.cs
index 7a17de018..3fcdb9af7 100644
--- a/src/Microsoft.OpenApi/Reader/V3/OpenApiDocumentDeserializer.cs
+++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiDocumentDeserializer.cs
@@ -54,7 +54,7 @@ public static OpenApiDocument LoadOpenApi(RootNode rootNode)
             ParseMap(openApiNode, openApiDoc, _openApiFixedFields, _openApiPatternFields, openApiDoc);
 
             // Register components
-            openApiDoc.Workspace.RegisterComponents(openApiDoc, OpenApiSpecVersion.OpenApi3_0);
+            openApiDoc.Workspace.RegisterComponents(openApiDoc);
 
             return openApiDoc;
         }
diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiDocumentDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiDocumentDeserializer.cs
index b6e0fe5fc..8137fb460 100644
--- a/src/Microsoft.OpenApi/Reader/V31/OpenApiDocumentDeserializer.cs
+++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiDocumentDeserializer.cs
@@ -53,7 +53,7 @@ public static OpenApiDocument LoadOpenApi(RootNode rootNode)
             ParseMap(openApiNode, openApiDoc, _openApiFixedFields, _openApiPatternFields, openApiDoc);
 
             // Register components
-            openApiDoc.Workspace.RegisterComponents(openApiDoc, OpenApiSpecVersion.OpenApi3_1);
+            openApiDoc.Workspace.RegisterComponents(openApiDoc);
 
             return openApiDoc;
         }
diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiV31Deserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiV31Deserializer.cs
index a56590bf1..d6c9d0fcf 100644
--- a/src/Microsoft.OpenApi/Reader/V31/OpenApiV31Deserializer.cs
+++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiV31Deserializer.cs
@@ -157,9 +157,11 @@ private static (string, string) GetReferenceIdAndExternalResource(string pointer
             string refId = !pointer.Contains('#') ? pointer : refSegments.Last();
 
             var isExternalResource = !refSegments.First().StartsWith("#");
-            string externalResource = isExternalResource
-                ? $"{refSegments.First()}/{refSegments[1].TrimEnd('#')}"
-                : null;
+            string externalResource = null;
+            if (isExternalResource && pointer.Contains('#'))
+            {
+                externalResource = $"{refSegments.First()}/{refSegments[1].TrimEnd('#')}";
+            }
 
             return (refId, externalResource);
         }
diff --git a/src/Microsoft.OpenApi/Services/OpenApiComponentsRegistryExtensions.cs b/src/Microsoft.OpenApi/Services/OpenApiComponentsRegistryExtensions.cs
deleted file mode 100644
index 226853a13..000000000
--- a/src/Microsoft.OpenApi/Services/OpenApiComponentsRegistryExtensions.cs
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT license.
-
-using Microsoft.OpenApi.Extensions;
-using Microsoft.OpenApi.Models;
-
-namespace Microsoft.OpenApi.Services
-{
-    internal static class OpenApiComponentsRegistryExtensions
-    {
-        public static void RegisterComponents(this OpenApiWorkspace workspace, OpenApiDocument document, OpenApiSpecVersion version = OpenApiSpecVersion.OpenApi3_0)
-        {
-            if (document?.Components == null) return;
-
-            string baseUri = document.BaseUri + OpenApiConstants.ComponentsSegment;
-            string location;
-
-            // Register Schema
-            foreach (var item in document.Components.Schemas)
-            {
-                if (item.Value.Id != null)
-                {
-                    location = item.Value.Id;
-                }
-                else
-                {
-                    location = baseUri + ReferenceType.Schema.GetDisplayName() + "/" + item.Key;
-                }
-
-                workspace.RegisterComponent(location, item.Value);
-            }
-
-            // Register Parameters
-            foreach (var item in document.Components.Parameters)
-            {
-                location = baseUri + ReferenceType.Parameter.GetDisplayName() + "/" + item.Key;
-                workspace.RegisterComponent(location, item.Value);
-            }
-
-            // Register Responses
-            foreach (var item in document.Components.Responses)
-            {
-                location = baseUri + ReferenceType.Response.GetDisplayName() + "/" + item.Key;
-                workspace.RegisterComponent(location, item.Value);
-            }
-
-            // Register RequestBodies
-            foreach (var item in document.Components.RequestBodies)
-            {
-                location = baseUri + ReferenceType.RequestBody.GetDisplayName() + "/" + item.Key;
-                workspace.RegisterComponent(location, item.Value);
-            }
-
-            // Register Links
-            foreach (var item in document.Components.Links)
-            {
-                location = baseUri + ReferenceType.Link.GetDisplayName() + "/" + item.Key;
-                workspace.RegisterComponent(location, item.Value);
-            }
-
-            // Register Callbacks
-            foreach (var item in document.Components.Callbacks)
-            {
-                location = baseUri + ReferenceType.Callback.GetDisplayName() + "/" + item.Key;
-                workspace.RegisterComponent(location, item.Value);
-            }
-
-            // Register PathItems
-            foreach (var item in document.Components.PathItems)
-            {
-                location = baseUri + ReferenceType.PathItem.GetDisplayName() + "/" + item.Key;
-                workspace.RegisterComponent(location, item.Value);
-            }
-
-            // Register Examples
-            foreach (var item in document.Components.Examples)
-            {
-                location = baseUri + ReferenceType.Example.GetDisplayName() + "/" + item.Key;
-                workspace.RegisterComponent(location, item.Value);
-            }
-
-            // Register Headers
-            foreach (var item in document.Components.Headers)
-            {
-                location = baseUri + ReferenceType.Header.GetDisplayName() + "/" + item.Key;
-                workspace.RegisterComponent(location, item.Value);
-            }
-
-            // Register SecuritySchemes
-            foreach (var item in document.Components.SecuritySchemes)
-            {
-                location = baseUri + ReferenceType.SecurityScheme.GetDisplayName() + "/" + item.Key;
-                workspace.RegisterComponent(location, item.Value);
-            }
-        }
-    }
-}
diff --git a/src/Microsoft.OpenApi/Services/OpenApiWorkspace.cs b/src/Microsoft.OpenApi/Services/OpenApiWorkspace.cs
index 319a5d63f..7652ed242 100644
--- a/src/Microsoft.OpenApi/Services/OpenApiWorkspace.cs
+++ b/src/Microsoft.OpenApi/Services/OpenApiWorkspace.cs
@@ -4,6 +4,7 @@
 using System;
 using System.Collections.Generic;
 using System.IO;
+using Microsoft.OpenApi.Extensions;
 using Microsoft.OpenApi.Interfaces;
 using Microsoft.OpenApi.Models;
 
@@ -54,6 +55,90 @@ public int ComponentsCount()
             return _IOpenApiReferenceableRegistry.Count + _artifactsRegistry.Count;
         }
 
+        /// 
+        /// Registers a document's components into the workspace
+        /// 
+        /// 
+        public void RegisterComponents(OpenApiDocument document)
+        {
+            if (document?.Components == null) return;
+
+            string baseUri = document.BaseUri + OpenApiConstants.ComponentsSegment;
+            string location;
+
+            // Register Schema
+            foreach (var item in document.Components.Schemas)
+            {
+                location = item.Value.Id ?? baseUri + ReferenceType.Schema.GetDisplayName() + "/" + item.Key;
+
+                RegisterComponent(location, item.Value);
+            }
+
+            // Register Parameters
+            foreach (var item in document.Components.Parameters)
+            {
+                location = baseUri + ReferenceType.Parameter.GetDisplayName() + "/" + item.Key;
+                RegisterComponent(location, item.Value);
+            }
+
+            // Register Responses
+            foreach (var item in document.Components.Responses)
+            {
+                location = baseUri + ReferenceType.Response.GetDisplayName() + "/" + item.Key;
+                RegisterComponent(location, item.Value);
+            }
+
+            // Register RequestBodies
+            foreach (var item in document.Components.RequestBodies)
+            {
+                location = baseUri + ReferenceType.RequestBody.GetDisplayName() + "/" + item.Key;
+                RegisterComponent(location, item.Value);
+            }
+
+            // Register Links
+            foreach (var item in document.Components.Links)
+            {
+                location = baseUri + ReferenceType.Link.GetDisplayName() + "/" + item.Key;
+                RegisterComponent(location, item.Value);
+            }
+
+            // Register Callbacks
+            foreach (var item in document.Components.Callbacks)
+            {
+                location = baseUri + ReferenceType.Callback.GetDisplayName() + "/" + item.Key;
+                RegisterComponent(location, item.Value);
+            }
+
+            // Register PathItems
+            foreach (var item in document.Components.PathItems)
+            {
+                location = baseUri + ReferenceType.PathItem.GetDisplayName() + "/" + item.Key;
+                RegisterComponent(location, item.Value);
+            }
+
+            // Register Examples
+            foreach (var item in document.Components.Examples)
+            {
+                location = baseUri + ReferenceType.Example.GetDisplayName() + "/" + item.Key;
+                RegisterComponent(location, item.Value);
+            }
+
+            // Register Headers
+            foreach (var item in document.Components.Headers)
+            {
+                location = baseUri + ReferenceType.Header.GetDisplayName() + "/" + item.Key;
+                RegisterComponent(location, item.Value);
+            }
+
+            // Register SecuritySchemes
+            foreach (var item in document.Components.SecuritySchemes)
+            {
+                location = baseUri + ReferenceType.SecurityScheme.GetDisplayName() + "/" + item.Key;
+                RegisterComponent(location, item.Value);
+            }
+        }
+
+
         /// 
         /// Registers a component in the component registry.
         /// 
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiDocumentTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiDocumentTests.cs
index 2ada8e4bd..c954387a6 100644
--- a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiDocumentTests.cs
+++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiDocumentTests.cs
@@ -1,15 +1,17 @@
 using System.Collections.Generic;
 using System.Globalization;
 using System.IO;
+using System.Threading.Tasks;
 using FluentAssertions;
 using Microsoft.OpenApi.Extensions;
-using Microsoft.OpenApi.Interfaces;
 using Microsoft.OpenApi.Models;
 using Microsoft.OpenApi.Models.References;
 using Microsoft.OpenApi.Reader;
 using Microsoft.OpenApi.Tests;
 using Microsoft.OpenApi.Writers;
+using Microsoft.OpenApi.Services;
 using Xunit;
+using System.Linq;
 
 namespace Microsoft.OpenApi.Readers.Tests.V31Tests
 {
@@ -392,7 +394,7 @@ public void ParseDocumentsWithReusablePathItemInWebhooksSucceeds()
     new OpenApiDiagnostic() { SpecificationVersion = OpenApiSpecVersion.OpenApi3_1 });
 
             var outputWriter = new StringWriter(CultureInfo.InvariantCulture);
-            var writer = new OpenApiJsonWriter(outputWriter, new() { InlineLocalReferences = true } );
+            var writer = new OpenApiJsonWriter(outputWriter, new() { InlineLocalReferences = true });
             actual.OpenApiDocument.SerializeAsV31(writer);
             var serialized = outputWriter.ToString();
         }
@@ -445,7 +447,7 @@ public void ParseDocumentWithPatternPropertiesInSchemaWorks()
                     }
                 }
             };
-            
+
             // Serialization
             var mediaType = result.OpenApiDocument.Paths["/example"].Operations[OperationType.Get].Responses["200"].Content["application/json"];
 
@@ -461,7 +463,7 @@ public void ParseDocumentWithPatternPropertiesInSchemaWorks()
       type: string
     prop3:
       type: string";
-            
+
             var actualMediaType = mediaType.SerializeAsYaml(OpenApiSpecVersion.OpenApi3_1);
 
             // Assert
@@ -484,5 +486,49 @@ public void ParseDocumentWithReferenceByIdGetsResolved()
             Assert.Equal("object", requestBodySchema.Type);
             Assert.Equal("string", parameterSchema.Type);
         }
+
+        [Fact]
+        public async Task ExternalDocumentDereferenceToOpenApiDocumentUsingJsonPointerWorks()
+        {
+            // Arrange
+            var path = Path.Combine(Directory.GetCurrentDirectory(), SampleFolderPath);
+
+            var settings = new OpenApiReaderSettings
+            {
+                LoadExternalRefs = true,
+                BaseUrl = new(path),
+            };
+
+            // Act
+            var result = await OpenApiDocument.LoadAsync(Path.Combine(SampleFolderPath, "externalRefByJsonPointer.yaml"), settings);
+            var responseSchema = result.OpenApiDocument.Paths["/resource"].Operations[OperationType.Get].Responses["200"].Content["application/json"].Schema;
+
+            // Assert
+            result.OpenApiDocument.Workspace.Contains("./externalResource.yaml");
+            responseSchema.Properties.Count.Should().Be(2); // reference has been resolved
+        }
+
+        [Fact]
+        public async Task ParseExternalDocumentDereferenceToOpenApiDocumentByIdWorks()
+        {
+            // Arrange
+            var path = Path.Combine(Directory.GetCurrentDirectory(), SampleFolderPath);
+
+            var settings = new OpenApiReaderSettings
+            {
+                LoadExternalRefs = true,
+                BaseUrl = new(path),
+            };
+
+            // Act
+            var result = await OpenApiDocument.LoadAsync(Path.Combine(SampleFolderPath, "externalRefById.yaml"), settings);
+            var doc2 = OpenApiDocument.Load(Path.Combine(SampleFolderPath, "externalResource.yaml")).OpenApiDocument;
+
+            var requestBodySchema = result.OpenApiDocument.Paths["/resource"].Operations[OperationType.Get].Parameters.First().Schema;
+            result.OpenApiDocument.Workspace.RegisterComponents(doc2);
+
+            // Assert
+            requestBodySchema.Properties.Count.Should().Be(2); // reference has been resolved
+        }
     }
 }
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiDocument/externalRefById.yaml b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiDocument/externalRefById.yaml
new file mode 100644
index 000000000..bb3755180
--- /dev/null
+++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiDocument/externalRefById.yaml
@@ -0,0 +1,14 @@
+openapi: 3.1.0
+info:
+  title: ReferenceById
+  version: 1.0.0
+paths:
+  /resource:
+    get:
+      parameters:
+        - name: id
+          in: query
+          required: true
+          schema:
+            $ref: 'https://example.com/schemas/user.json'
+components: {}
\ No newline at end of file
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiDocument/externalRefByJsonPointer.yaml b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiDocument/externalRefByJsonPointer.yaml
new file mode 100644
index 000000000..913b20e7c
--- /dev/null
+++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiDocument/externalRefByJsonPointer.yaml
@@ -0,0 +1,15 @@
+openapi: 3.1.0
+info:
+  title: ReferenceById
+  version: 1.0.0
+paths:
+  /resource:
+    get:
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: './externalResource.yaml#/components/schemas/todo'
+components: {}
\ No newline at end of file
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiDocument/externalResource.yaml b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiDocument/externalResource.yaml
new file mode 100644
index 000000000..78d6c0851
--- /dev/null
+++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiDocument/externalResource.yaml
@@ -0,0 +1,22 @@
+openapi: 3.1.0
+info:
+  title: ReferencedById
+  version: 1.0.0
+paths: {}
+components:
+  schemas:
+    todo:
+      type: object
+      properties:
+        id:
+           type: string
+        name:
+           type: string
+    user:
+       $id: 'https://example.com/schemas/user.json'
+       type: object
+       properties:
+         id:
+           type: string
+         name:
+           type: string
\ No newline at end of file
diff --git a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiPathItemReferenceTests.cs b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiPathItemReferenceTests.cs
index ec532bed7..2d7354f78 100644
--- a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiPathItemReferenceTests.cs
+++ b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiPathItemReferenceTests.cs
@@ -83,8 +83,8 @@ public OpenApiPathItemReferenceTests()
             _openApiDoc = OpenApiDocument.Parse(OpenApi, OpenApiConstants.Yaml).OpenApiDocument;
             _openApiDoc_2 = OpenApiDocument.Parse(OpenApi_2, OpenApiConstants.Yaml).OpenApiDocument;
             _openApiDoc.Workspace.AddDocumentId("https://myserver.com/beta", _openApiDoc_2.BaseUri);
-            _openApiDoc.Workspace.RegisterComponents(_openApiDoc_2, OpenApiSpecVersion.OpenApi3_1);
-            _openApiDoc_2.Workspace.RegisterComponents(_openApiDoc_2, OpenApiSpecVersion.OpenApi3_1);
+            _openApiDoc.Workspace.RegisterComponents(_openApiDoc_2);
+            _openApiDoc_2.Workspace.RegisterComponents(_openApiDoc_2);
 
             _localPathItemReference = new OpenApiPathItemReference("userPathItem", _openApiDoc_2)
             {
diff --git a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt
index 7eb01a70c..00b16a254 100755
--- a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt
+++ b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt
@@ -1512,6 +1512,7 @@ namespace Microsoft.OpenApi.Services
         public bool Contains(string location) { }
         public System.Uri GetDocumentId(string key) { }
         public bool RegisterComponent(string location, T component) { }
+        public void RegisterComponents(Microsoft.OpenApi.Models.OpenApiDocument document) { }
         public T ResolveReference(string location) { }
     }
     public class OperationSearch : Microsoft.OpenApi.Services.OpenApiVisitorBase