diff --git a/CHANGELOG b/CHANGELOG
index a6e36d2891c1ec9e873814281574adc94ddd82db..86db56ad63814bb83ac79ddd4fb93b101f209299 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,4 +1,5 @@
 minerva (14.0.0~beta.2) unstable; urgency=low
+  * Bug fix: exported SBML passes online validation (#831)
   * Bug fix: allow user to remove own comments (#931)
   * Bug fix: validation of project name length is provided (#950)
   * Bug fix: after reducing privileges on himself interface is refreshed (#948)
diff --git a/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/reaction/SbmlReactionExporter.java b/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/reaction/SbmlReactionExporter.java
index 4bf203532dbe74413bec5d4d06f29d0be383bcfc..d4184cb7b4e211f4b6370c32635b14e4976af7a3 100644
--- a/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/reaction/SbmlReactionExporter.java
+++ b/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/reaction/SbmlReactionExporter.java
@@ -1,16 +1,15 @@
 package lcsb.mapviewer.converter.model.sbml.reaction;
 
-import java.awt.*;
+import java.awt.BasicStroke;
+import java.awt.Stroke;
 import java.awt.geom.Line2D;
 import java.awt.geom.Point2D;
 import java.util.*;
-import java.util.List;
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.sbml.jsbml.*;
 import org.sbml.jsbml.ext.layout.*;
-import org.sbml.jsbml.ext.layout.Point;
 import org.sbml.jsbml.ext.render.*;
 import org.w3c.dom.Node;
 
@@ -237,13 +236,45 @@ public class SbmlReactionExporter extends SbmlBioEntityExporter<Reaction, org.sb
       reactionGlyph.setBoundingBox(new BoundingBox());
     }
     if (reactionGlyph.getBoundingBox().getPosition() == null) {
-      reactionGlyph.getBoundingBox().setPosition(new Point());
+      reactionGlyph.getBoundingBox().setPosition(curveToPoint(reactionGlyph.getCurve()));
+      reactionGlyph.getBoundingBox().setDimensions(curveToDimension(reactionGlyph.getCurve()));
     }
     reactionGlyph.getBoundingBox().getPosition().setZ(reaction.getZ());
 
     removeColinearPoints(reactionGlyph);
   }
 
+  private Dimensions curveToDimension(Curve curve) {
+    Point p = curveToPoint(curve);
+    double x = Double.MIN_VALUE;
+    double y = Double.MIN_VALUE;
+    for (int i = 0; i < curve.getCurveSegmentCount(); i++) {
+      LineSegment segment = (LineSegment) curve.getCurveSegment(i);
+      x = Math.max(x, segment.getStart().getX());
+      x = Math.max(x, segment.getEnd().getX());
+
+      y = Math.max(y, segment.getStart().getY());
+      y = Math.max(y, segment.getEnd().getY());
+
+    }
+    return new Dimensions(x - p.getX(), y - p.getY(), 0, getSbmlModel().getLevel(), getSbmlModel().getVersion());
+  }
+
+  private Point curveToPoint(Curve curve) {
+    double x = Double.MAX_VALUE;
+    double y = Double.MAX_VALUE;
+    for (int i = 0; i < curve.getCurveSegmentCount(); i++) {
+      LineSegment segment = (LineSegment) curve.getCurveSegment(i);
+      x = Math.min(x, segment.getStart().getX());
+      x = Math.min(x, segment.getEnd().getX());
+
+      y = Math.min(y, segment.getStart().getY());
+      y = Math.min(y, segment.getEnd().getY());
+
+    }
+    return new Point(x, y);
+  }
+
   @Override
   protected AbstractReferenceGlyph createElementGlyph(String sbmlElementId, String glyphId) {
     int separatorIndex = glyphId.indexOf("__");
diff --git a/converter-sbml/src/test/java/lcsb/mapviewer/converter/model/sbml/AllSbmlConverterTests.java b/converter-sbml/src/test/java/lcsb/mapviewer/converter/model/sbml/AllSbmlConverterTests.java
index 69a6def9d470176ca912ff0471997393eaf21efd..bfd1a1fb25345e09d433aabbf1e5449b19457457 100644
--- a/converter-sbml/src/test/java/lcsb/mapviewer/converter/model/sbml/AllSbmlConverterTests.java
+++ b/converter-sbml/src/test/java/lcsb/mapviewer/converter/model/sbml/AllSbmlConverterTests.java
@@ -26,6 +26,7 @@ import lcsb.mapviewer.converter.model.sbml.species.AllSbmlSpeciesTests;
     SbmlExporterFromCellDesignerTest.class,
     SbmlPareserForInvalidReactionTest.class,
     SbmlParserTest.class,
+    SbmlValidationTests.class,
 })
 public class AllSbmlConverterTests {
 
diff --git a/converter-sbml/src/test/java/lcsb/mapviewer/converter/model/sbml/SbmlValidationTests.java b/converter-sbml/src/test/java/lcsb/mapviewer/converter/model/sbml/SbmlValidationTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..171cd9c3bfd8048a478c0efc245912079228149c
--- /dev/null
+++ b/converter-sbml/src/test/java/lcsb/mapviewer/converter/model/sbml/SbmlValidationTests.java
@@ -0,0 +1,79 @@
+package lcsb.mapviewer.converter.model.sbml;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.mime.MultipartEntityBuilder;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+import lcsb.mapviewer.common.XmlParser;
+import lcsb.mapviewer.converter.ConverterParams;
+import lcsb.mapviewer.model.map.model.Model;
+
+@RunWith(Parameterized.class)
+public class SbmlValidationTests extends SbmlTestFunctions {
+  Logger logger = LogManager.getLogger();
+
+  String filename;
+
+  public SbmlValidationTests(String filename) {
+    this.filename = filename;
+  }
+
+  @Parameters(name = "{0}")
+  public static Collection<Object[]> data() throws IOException {
+    List<Object[]> result = new ArrayList<>();
+    result.add(new Object[] { "testFiles/small/empty.xml" });
+    result.add(new Object[] { "testFiles/small/reaction/dissociation.xml" });
+    return result;
+  }
+
+  @Test
+  public void testIsValidSbml() throws Exception {
+    SbmlParser parser = new SbmlParser();
+    Model model = parser.createModel(new ConverterParams().filename(filename));
+    String xml = parser.model2String(model);
+
+    CloseableHttpClient httpClient = HttpClients.createDefault();
+    HttpPost uploadFile = new HttpPost("http://sbml.org/validator/");
+    MultipartEntityBuilder builder = MultipartEntityBuilder.create();
+    builder.addTextBody("file", xml, ContentType.TEXT_PLAIN);
+    builder.addBinaryBody(
+        "file",
+        new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8)),
+        ContentType.APPLICATION_OCTET_STREAM,
+        filename);
+    builder.addTextBody("output", "xml", ContentType.TEXT_PLAIN);
+    builder.addTextBody("offcheck", "u,r", ContentType.TEXT_PLAIN);
+
+    HttpEntity multipart = builder.build();
+    uploadFile.setEntity(multipart);
+    CloseableHttpResponse response = httpClient.execute(uploadFile);
+    String responseXml = EntityUtils.toString(response.getEntity());
+    Document document = XmlParser.getXmlDocumentFromString(responseXml);
+    List<Node> problems = XmlParser.getAllNotNecessirellyDirectChild("problem", document);
+    if (problems.size() > 0) {
+      logger.debug(responseXml);
+    }
+    assertEquals("SBML is invalid", 0, problems.size());
+  }
+
+}