diff --git a/src/liboggz/metric_internal.c b/src/liboggz/metric_internal.c
index f024b37d65fb56c757cd298ccee60fea855b15c2..9e3d16b70a0731aaada8c3d14b0682f3364bc00c 100644
--- a/src/liboggz/metric_internal.c
+++ b/src/liboggz/metric_internal.c
@@ -51,6 +51,12 @@ oggz_metric_dirac (OGGZ * oggz, long serialno,
   stream = oggz_get_stream (oggz, serialno);
   if (stream == NULL) return -1;
 
+  /* we divide by the granulerate, so ensure denominator is non-zero.
+   * Also drop negative ones as these indicate invalid value. */
+  if (stream->granulerate_n <= 0) {
+    return -1;
+  }
+
   iframe = granulepos >> stream->granuleshift;
   pframe = granulepos - (iframe << stream->granuleshift);
   pt = (iframe + pframe) >> 9;
@@ -78,6 +84,12 @@ oggz_metric_vp8 (OGGZ * oggz, long serialno,
   stream = oggz_get_stream (oggz, serialno);
   if (stream == NULL) return -1;
 
+  /* we divide by the granulerate, so ensure denominator is non-zero.
+   * Also drop negative ones as these indicate invalid value. */
+  if (stream->granulerate_n <= 0) {
+    return -1;
+  }
+
   frame = granulepos >> stream->granuleshift;
 
   units = frame * stream->granulerate_d / stream->granulerate_n;
@@ -101,6 +113,12 @@ oggz_metric_default_granuleshift (OGGZ * oggz, long serialno,
   stream = oggz_get_stream (oggz, serialno);
   if (stream == NULL) return -1;
 
+  /* we divide by the granulerate, so ensure denominator is non-zero.
+   * Also drop negative ones as these indicate invalid value. */
+  if (stream->granulerate_n <= 0) {
+    return -1;
+  }
+
   iframe = granulepos >> stream->granuleshift;
   pframe = granulepos - (iframe << stream->granuleshift);
   granulepos = iframe + pframe;
@@ -125,6 +143,12 @@ oggz_metric_default_linear (OGGZ * oggz, long serialno, ogg_int64_t granulepos,
   stream = oggz_get_stream (oggz, serialno);
   if (stream == NULL) return -1;
 
+  /* we divide by the granulerate, so ensure denominator is non-zero.
+   * Also drop negative ones as these indicate invalid value. */
+  if (stream->granulerate_n <= 0) {
+    return -1;
+  }
+
   granulepos = granulepos <= stream->first_granule
     ? 0 : granulepos - stream->first_granule;
   return (stream->granulerate_d * granulepos / stream->granulerate_n);
@@ -141,7 +165,7 @@ oggz_metric_update (OGGZ * oggz, long serialno)
   if (stream == NULL) return OGGZ_ERR_BAD_SERIALNO;
 
   /* we divide by the granulerate, ie. mult by gr_d/gr_n, so ensure
-   * numerator is non-zero */
+   * denominator is non-zero */
   if (stream->granulerate_n == 0) {
     stream->granulerate_n= 1;
     stream->granulerate_d = 0;
@@ -206,6 +230,12 @@ oggz_set_granulerate (OGGZ * oggz, long serialno,
   stream = oggz_get_stream (oggz, serialno);
   if (stream == NULL) return OGGZ_ERR_BAD_SERIALNO;
 
+  /* we divide by the granulerate, so ensure denominator is non-zero.
+   * Also drop negative ones as these indicate invalid value. */
+  if (granule_rate_numerator == 0) {
+    return OGGZ_ERR_BAD_GRANULEPOS;
+  }
+
   stream->granulerate_n = granule_rate_numerator;
   stream->granulerate_d = granule_rate_denominator;
 
@@ -259,6 +289,12 @@ oggz_set_metric_linear (OGGZ * oggz, long serialno,
   stream = oggz_get_stream (oggz, serialno);
   if (stream == NULL) return OGGZ_ERR_BAD_SERIALNO;
 
+  /* we divide by the granulerate, so ensure denominator is non-zero.
+   * Also drop negative ones as these indicate invalid value. */
+  if (granule_rate_numerator == 0) {
+    return OGGZ_ERR_BAD_GRANULEPOS;
+  }
+
   stream->granulerate_n = granule_rate_numerator;
   stream->granulerate_d = granule_rate_denominator;
   stream->granuleshift = 0;