diff --git a/lib/ex_doc/formatter/epub.ex b/lib/ex_doc/formatter/epub.ex
index 6c14b693f..5d4111b72 100644
--- a/lib/ex_doc/formatter/epub.ex
+++ b/lib/ex_doc/formatter/epub.ex
@@ -50,6 +50,23 @@ defmodule ExDoc.Formatter.EPUB do
     Path.relative_to_cwd(epub)
   end
 
+  @doc """
+  Helper that replaces anchor names and links that could potentially cause problems on EPUB documents
+
+  This helper replaces all the `&` with `&` found in anchors like
+  `Kernel.xhtml#&&/2` or `
...
`
+
+  These anchor names cause a fatal error while EPUB readers parse the files,
+  resulting in truncated content.
+
+  For more details, see: https://github.com/elixir-lang/ex_doc/issues/1851
+  """
+  def fix_anchors(content) do
+    content
+    |> String.replace(~r{id="&+/\d+[^"]*}, &String.replace(&1, "&", "&"))
+    |> String.replace(~r{href="[^#"]*#&+/\d+[^"]*}, &String.replace(&1, "&", "&"))
+  end
+
   defp normalize_config(config) do
     output =
       config.output
@@ -63,7 +80,11 @@ defmodule ExDoc.Formatter.EPUB do
     for {_title, extras} <- config.extras do
       Enum.each(extras, fn %{id: id, title: title, title_content: title_content, content: content} ->
         output = "#{config.output}/OEBPS/#{id}.xhtml"
-        html = Templates.extra_template(config, title, title_content, content)
+
+        html =
+          config
+          |> Templates.extra_template(title, title_content, content)
+          |> fix_anchors()
 
         if File.regular?(output) do
           ExDoc.Utils.warn("file #{Path.relative_to_cwd(output)} already exists", [])
@@ -157,7 +178,11 @@ defmodule ExDoc.Formatter.EPUB do
   end
 
   defp generate_module_page(module_node, config) do
-    content = Templates.module_page(config, module_node)
+    content =
+      config
+      |> Templates.module_page(module_node)
+      |> fix_anchors()
+
     File.write("#{config.output}/OEBPS/#{module_node.id}.xhtml", content)
   end
 
diff --git a/lib/ex_doc/formatter/epub/templates/nav_template.eex b/lib/ex_doc/formatter/epub/templates/nav_template.eex
index cc1bfa691..4d041b22a 100644
--- a/lib/ex_doc/formatter/epub/templates/nav_template.eex
+++ b/lib/ex_doc/formatter/epub/templates/nav_template.eex
@@ -5,15 +5,11 @@
         <%= nav_grouped_item_template config.extras  %>
 
         <%= unless Enum.empty?(nodes.modules) do %>
-        
-          
-            - Modules
-              
-              <%= nav_grouped_item_template nodes.modules  %>
-               -
-
-        
+          Modules
+
+            <%= nav_grouped_item_template nodes.modules  %>
+            
+          
         <% end %>
         <%= nav_item_template "Mix Tasks", nodes.tasks %>
       
diff --git a/test/ex_doc/formatter/epub_test.exs b/test/ex_doc/formatter/epub_test.exs
index c1f02225c..eeb8681c9 100644
--- a/test/ex_doc/formatter/epub_test.exs
+++ b/test/ex_doc/formatter/epub_test.exs
@@ -151,6 +151,9 @@ defmodule ExDoc.Formatter.EPUBTest do
     assert content =~
              ~r{TypesAndSpecs.Sub}
 
+    assert content =~
+             ~r{&&/2}
+
     content = File.read!(tmp_dir <> "/epub/OEBPS/nav.xhtml")
     assert content =~ ~r{README}
   end
@@ -248,4 +251,19 @@ defmodule ExDoc.Formatter.EPUBTest do
   after
     File.rm_rf!("test/tmp/epub_assets")
   end
+
+  describe "fix_anchors/1" do
+    test "adapts anchor names to avoid parsing errors from EPUB readers" do
+      for {source, expected} <- [
+            {~S|its documentation|,
+             ~S|its documentation|},
+            {~S|&&/2|,
+             ~S|&&/2|},
+            {~S|title
|,
+             ~S|title
|}
+          ] do
+        assert ExDoc.Formatter.EPUB.fix_anchors(source) == expected
+      end
+    end
+  end
 end
diff --git a/test/fixtures/README.md b/test/fixtures/README.md
index 6963347fa..ab032b853 100644
--- a/test/fixtures/README.md
+++ b/test/fixtures/README.md
@@ -15,3 +15,7 @@ hello
 ## more > than
 
 raw content
+
+The following text includes a reference to an anchor that causes problems in EPUB documents.
+
+To remove this anti-pattern, we can replace `&&/2`, `||/2`, and `!/1` by `and/2`, `or/2`, and `not/1` respectively.